// Frame_window - окно приложения, Class и Delta - значения приоритета. VOID Priority_SetPriorityLevel( HWND Frame_window, LONG Class, LONG Delta ) { // Если это окно создано самой оболочкой Presentation Manager - возврат. if( IsPMShellAuxiliaryWindow( Frame_window ) ) return; // Узнаем приложение, создавшее окно. // Для окон VIO здесь возвращается их настоящий PID, а не PID окна (оно создаётся оболочкой PM). PID Process_ID = QueryWindowRealProcessID( Frame_window ); // Пробуем изменить приоритет на месте. APIRET Result = NO_ERROR; if( Process_ID != 0 ) Result = DosSetPriority( PRTYS_PROCESSTREE, Class, Delta, Process_ID ); // Если это сделать не удалось: if( Result != NO_ERROR ) { // Запоминаем значения приоритета для окна. SetProperty( Frame_window, PRP_PRIORITY_CLASS, &Class ); SetProperty( Frame_window, PRP_PRIORITY_DELTA, &Delta ); // Узнаем окно рабочего стола. HWND Desktop = QueryDesktopWindow(); // Посылаем в очередь окна рабочего стола сообщение WM_MARK. Приоритет можно будет изменить во время его получения. HMQ Desktop_queue = WinQueryWindowULong( Desktop, QWL_HMQ ); WinPostQueueMsg( Desktop_queue, WM_MARK, (MPARAM) MRK_SET_PRIORITY, (MPARAM) Frame_window ); // Посылаем такое же сообщение в очередь окна. Текстовые окна используют ту же очередь, что и окно рабочего стола, поэтому второй раз посылать им сообщение не надо. HMQ Window_queue = WinQueryWindowULong( Frame_window, QWL_HMQ ); if( Window_queue != Desktop_queue ) WinPostQueueMsg( Window_queue, WM_MARK, (MPARAM) MRK_SET_PRIORITY, (MPARAM) Frame_window ); } // Возврат. return; }
// Все переменные - внешние. VOID ApplierSendMsgHook( HAB Application, PSMHSTRUCT Message ) { // Если надо выполнять действия с окнами диалогов: if( Applier.Settings.Script_after_Logon || Applier.Settings.Remember_dialog_fields || Applier.Settings.Send_Yes ) if( !RoomsChangeIsInProcess() ) { // Если окно рамки становится видимым: if( TopFrameWindowIsShowing( Message ) ) { // Узнаем окно рамки. HWND Frame_window = QueryFrameWindow( Message->hwnd ); // Если такое окно содержит поля для ввода пароля и их значения надо забрать: if( Applier.Settings.Script_after_Logon ) if( Applier_WindowIsPresentInLogonDialogList( Frame_window, 0 ) ) { // Посылаем в очередь сообщение WM_MARK. Когда оно будет получено, окно подготовит все свои кнопки и можно будет проверять его заголовок. HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ ); WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_LOGON_WINDOW, (MPARAM) Frame_window ); } // Если в таком окне надо заполнять поля при его появлении: if( Applier.Settings.Remember_dialog_fields ) if( Applier_WindowIsPresentInIncompleteDialogList( Frame_window, 0 ) ) { // Посылаем в очередь сообщение WM_MARK. Когда оно будет получено, окно подготовит все свои кнопки и можно будет проверять его заголовок. HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ ); WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_COMPLETE_DIALOG, (MPARAM) Frame_window ); } // Если это окно надо закрывать при появлении: if( Applier.Settings.Send_Yes ) if( Applier_WindowIsPresentInMessageDialogList( Frame_window, 0 ) ) { // Посылаем в очередь сообщение WM_MARK. Когда оно будет получено, окно подготовит все свои кнопки и можно будет проверять его заголовок. HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ ); WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_SEND_YES, (MPARAM) Frame_window ); } } // Если есть окна для ввода пароля и одно из окон закрывается: if( Applier.RTSettings.Logon_in_process ) if( Message->msg == WM_DESTROY ) { // Если окно есть в списке отслеживаемых окон: for( INT Count = APPLIER_MONITORING_LOGON_WINDOWS - 1; Count >= 0; Count -- ) if( Applier.RTDlgMemory.Logon_windows[ Count ].Window == Message->hwnd ) { // Посылаем сообщение в поток. Он выполнит все необходимые проверки. WinPostQueueMsg( Enhancer.Modules.Applier->Message_queue, SM_LOGON_ACTION, (MPARAM) Message->hwnd, 0 ); break; } } // Если есть окна для ввода пароля и одно из окон становится выбранным: if( Applier.RTSettings.Logon_in_process ) if( TopFrameWindowIsActivating( Message ) ) { // Посылаем в поток сообщение о том, что надо проверить существование окон ввода пароля. WinPostQueueMsg( Enhancer.Modules.Applier->Message_queue, SM_LOGON_CHECK, 0, 0 ); } } // Возврат. return; }
// Все переменные - внешние. VOID VIOFontManagerInputHook( HAB Application, PQMSG Message, PBYTE Discarding ) { // Меняем шрифты для текстовых окон. if( VIOFontManager.Settings.Change_VIO_font_metrics ) { // Устанавливаем шрифт в окне. if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_SET_VIO_FONT ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp2; // Посылаем сообщение в поток. WinPostQueueMsg( Enhancer.Modules.Changer->Message_queue, SM_APPLY_VIO_FONT, (MPARAM) Frame_window, 0 ); } // Делаем окно видимым и выравниваем его по середине экрана. if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_SHOW_AND_ARRANGE ) { // Посылаем сообщение в поток. HWND Frame_window = (HWND) Message->mp2; WinPostQueueMsg( Enhancer.Modules.Changer->Message_queue, SM_SHOW_AND_ARRANGE, (MPARAM) Frame_window, 0 ); } } // Возврат. return; }
VOID MMKbdListener_StartThread( VOID ) { // Сбрасываем переменную для ответа от потока. Thread_responds.Thread_is_created = 0; // Если поток уже создан - выход. CHAR Semaphore_name[] = "\\SEM32\\NICE-OS2!Krnl!MMKbdListener"; HMTX hmtxAlreadyRunning = NULLHANDLE; if( DosOpenMutexSem( Semaphore_name, &hmtxAlreadyRunning ) == NO_ERROR ) return; else DosCreateMutexSem( Semaphore_name, &hmtxAlreadyRunning, DC_SEM_SHARED, 1 ); // Создаем поток. APIRET Thread_is_created = DosCreateThread( &Enhancer.Modules.MMKbdListener->Thread, (PFNTHREAD) MMKbdListener_MMKbdListenerThread, 0, 0, THREAD_STACK_SIZE ); // Если он создан - ждем, пока в нем будет создана очередь сообщений. if( Thread_is_created == NO_ERROR ) while( Thread_responds.Thread_is_created == 0 ) { Retard(); } // Если поток создать не удалось - возврат. if( Thread_is_created != NO_ERROR || Thread_responds.Thread_is_created == -1 ) { Enhancer.Modules.MMKbdListener->Thread = 0; return; } // Устанавливаем приоритет потока. WinPostQueueMsg( Enhancer.Modules.MMKbdListener->Message_queue, SM_PRIORITY, (MPARAM) PRTYC_REGULAR, (MPARAM) PRTYD_QUICK ); // Посылаем в поток сообщение о том, что ему следует вызвать функцию ожидания сообщений. WinPostQueueMsg( Enhancer.Modules.MMKbdListener->Message_queue, SM_WAIT_MMKBD_EVENTS, 0, 0 ); // Возврат. return; }
main(int argc, char *argv[], char *envp[]) { HAB hab; HMQ hmq; QMSG qmsg; char szBuf[MAX_BUF]; ATOM atom; hab = WinInitialize( 0 ); hmq = WinCreateMsgQueue( hab, 0 ); atom = WinAddAtom(WinQuerySystemAtomTable(), CLASS_NAME); if(Initialize(0, argv[0])) { WinPostQueueMsg(0, WM_QUIT, 1, 0); } else if(!InitApplication(0)) { char szEFailed[MAX_BUF]; if(NS_LoadString(0, IDS_ERROR_FAILED, szEFailed, MAX_BUF) == WIZ_OK) { sprintf(szBuf, szEFailed, "InitApplication()."); PrintError(szBuf, ERROR_CODE_SHOW); } WinPostQueueMsg(0, WM_QUIT, 1, 0); } else if(ParseUninstallIni(argc, argv)) { WinPostQueueMsg(0, WM_QUIT, 1, 0); } else if(ugUninstall.bUninstallFiles == TRUE) { if(diUninstall.bShowDialog == TRUE) hDlgUninstall = InstantiateDialog(hWndMain, DLG_UNINSTALL, diUninstall.szTitle, DlgProcUninstall); else ParseAllUninstallLogs(); } if((ugUninstall.bUninstallFiles == TRUE) && (diUninstall.bShowDialog == TRUE)) { while ( WinGetMsg( hab, &qmsg, NULLHANDLE, 0, 0 ) ) WinDispatchMsg( hab, &qmsg ); } /* Do clean up before exiting from the application */ DeInitialize(); WinDeleteAtom(WinQuerySystemAtomTable(), atom); WinDestroyMsgQueue( hmq ); WinTerminate( hab ); }
VOID Launcher_PostQuitMsg( VOID ) { // Посылаем сообщение в поток. WinPostQueueMsg( Enhancer.Modules.Launcher->Message_queue, WM_QUIT, 0, 0 ); // Возврат. return; }
// Все переменные - внешние. VOID ApplierInputHook( HAB Application, PQMSG Message, PBYTE Discarding ) { // Если надо выполнять действия с окнами диалогов: if( Applier.Settings.Script_after_Logon || Applier.Settings.Remember_dialog_fields || Applier.Settings.Send_Yes ) { // Запоминаем окна ввода пароля. Это сообщение посылается в окно в SendMsgHook() при обработке другого сообщения. if( Applier.Settings.Script_after_Logon ) if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_LOGON_WINDOW ) { // Посылаем сообщение в поток. HWND Frame_window = (HWND) Message->mp2; WinPostQueueMsg( Enhancer.Modules.Applier->Message_queue, SM_LOGON_WINDOW, (MPARAM) Frame_window, 0 ); } // Запоминаем значения в окнах ввода пароля. Это сообщение посылается в окно в SendMsgHook() при обработке другого сообщения. if( Applier.Settings.Script_after_Logon ) if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_LOGON_VALUES ) { // Посылаем сообщение в поток. HWND Frame_window = (HWND) Message->mp2; WinPostQueueMsg( Enhancer.Modules.Applier->Message_queue, SM_LOGON_VALUES, (MPARAM) Frame_window, 0 ); } // Восстанавливаем поля ввода в окнах диалогов. Это сообщение посылается в окно в SendMsgHook() при обработке другого сообщения. if( Applier.Settings.Remember_dialog_fields ) if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_COMPLETE_DIALOG ) { // Посылаем сообщение в поток. HWND Frame_window = (HWND) Message->mp2; WinPostQueueMsg( Enhancer.Modules.Applier->Message_queue, SM_COMPLETE_DIALOG, (MPARAM) Frame_window, 0 ); } // Закрываем окна диалогов. Это сообщение посылается в окно в SendMsgHook() при обработке другого сообщения. if( Applier.Settings.Send_Yes ) if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_SEND_YES ) { // Посылаем сообщение в поток. HWND Frame_window = (HWND) Message->mp2; WinPostQueueMsg( Enhancer.Modules.Applier->Message_queue, SM_SEND_YES, (MPARAM) Frame_window, 0 ); } } // Возврат. return; }
// Frame_window - окно рамки. VOID Diver_CheckWindowFrameDrawingNode( HWND Frame_window ) { // Посылаем сообщение в очередь. HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ ); WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_DRAW_FRAME, (MPARAM) Frame_window ); // Возврат. return; }
// Все переменные - внешние. VOID RoomsSendMsgHook( HAB Application, PSMHSTRUCT Message ) { // Если надо добавить комнаты к рабочему столу: if( Rooms.Settings.Create_Rooms ) if( !RoomsChangeIsInProcess() ) { // Если окно рамки становится выбранным: if( TopFrameWindowIsActivating( Message ) ) { // Узнаем окно рамки. HWND Frame_window = QueryFrameWindow( Message->hwnd ); // Запоминаем комнату, в которой располагается окно. Rooms_SetRoomProperty( Frame_window, GetCurrentOrNextRoom() ); // Делаем окно доступным для переключения. WinPostQueueMsg( Enhancer.Modules.Changer->Message_queue, SM_SET_JUMPABLE, (MPARAM) Frame_window, (MPARAM) SWL_JUMPABLE ); } // Если используется оболочка WPS: if( ShellIsWPS() ) { // Если окно оболочки скрыто: if( GetCurrentOrNextRoom() != SHELL_ROOM ) { // Если оно возвращается в обычное состояние или становится выбранным - надо спрятать его. if( TopFrameWindowIsMoving( Message ) || TopFrameWindowIsActivating( Message ) ) { // Узнаем окно рамки. HWND Frame_window = QueryFrameWindow( Message->hwnd ); // Если это окно WPS - посылаем в очередь сообщение WM_MARK. Когда оно будет получено, окно можно будет проверить. if( IsFolderWindow( Frame_window ) ) { HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ ); WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_CHECK_WINDOW, (MPARAM) Frame_window ); } } } } } // Возврат. return; }
SSMODULEDECLSPEC int SSMODULECALL SSModule_StopSaving(void) { // This is called when we have to stop saving. #ifdef DEBUG_LOGGING AddLog("[SSModule_StopSaving] : Enter!\n"); #endif if (!bRunning) { #ifdef DEBUG_LOGGING AddLog("[SSModule_StopSaving] : Not running, Leaving.\n"); #endif return SSMODULE_ERROR_NOTRUNNING; } #ifdef DEBUG_LOGGING AddLog("[SSModule_StopSaving] : Closing saver window\n"); #endif // Notify saver thread to stop! if (bOnlyPreviewMode) { // In preview mode, which means that there is no window created, but the // window was subclassed. So we cannot close the window, but we have to // post the WM_QUIT message into the thread's message queue to notify it // that this is the end of its job. WinPostQueueMsg(hmqSaverThreadMsgQueue, WM_QUIT, (MPARAM) NULL, (MPARAM) NULL); } else { // Close saver window WinPostMsg(hwndSaverWindow, WM_QUIT, (MPARAM) NULL, (MPARAM) NULL); } #ifdef DEBUG_LOGGING AddLog("[SSModule_StopSaving] : Waiting for thread to die\n"); #endif // Wait for the thread to stop DosWaitThread(&tidSaverThread, DCWW_WAIT); #ifdef DEBUG_LOGGING AddLog("[SSModule_StopSaving] : Screen saver stopped.\n"); #endif // Ok, screensaver stopped. bRunning = FALSE; free(CfgDlgInit.pchText); CfgDlgInit.pchText = NULL; return SSMODULE_NOERROR; }
// Все переменные - внешние. VOID VIOFontManagerSendMsgHook( HAB Application, PSMHSTRUCT Message ) { // Меняем шрифты для текстовых окон. if( VIOFontManager.Settings.Change_VIO_font_metrics ) if( !RoomsChangeIsInProcess() ) { // Если окно рамки становится видимым: if( TopFrameWindowIsShowing( Message ) ) { // Узнаем окно рамки. HWND Frame_window = QueryFrameWindow( Message->hwnd ); // Если это текстовое окно: if( IsVIOWindow( Frame_window ) ) { // Узнаем имя приложения, создавшего окно. CHAR Exe_name[ SIZE_OF_NAME ] = ""; GetDetectedExeName( Frame_window, Exe_name ); // Если его удалось определить: if( Exe_name[ 0 ] != 0 ) { // Если в окне надо менять шрифт - посылаем сообщение в поток, который это сделает. if( VIOFontManager_VIOFontMustBeChanged( Frame_window ) ) WinPostQueueMsg( Enhancer.Modules.Changer->Message_queue, SM_CHANGE_VIO_FONT, (MPARAM) Frame_window, 0 ); } // А если оно неизвестно - посылаем сообщение в поток, который подождет его некоторое время. else { WinPostQueueMsg( Enhancer.Modules.VIOMonitor->Message_queue, SM_MONITOR_VIO, (MPARAM) Frame_window, (MPARAM) SM_CHANGE_VIO_FONT ); } } } } // Возврат. return; }
static void ReleaseThreadQueue( PID pid, TID tid ) { HMQ hmq; int i; hmq = WinQueueFromID( HabDebugger, pid, tid ); if( hmq == NULLHANDLE ) return; for( i = 0; i < NumAssumedQueues; ++i ) { if( hmq == AssumedQueues[i] ) { WinPostQueueMsg( hmq, WM_QUIT, 0, 0 ); // break one soft mode loop AssumedQueues[i] = NULLHANDLE; break; } } }
/***************************************************************************** * Close: destroy KVA video thread output method ***************************************************************************** * Terminate an output method created by Open *****************************************************************************/ static void Close ( vlc_object_t *object ) { vout_display_t * vd = (vout_display_t *)object; vout_display_sys_t * sys = vd->sys; WinPostQueueMsg( sys->hmq, WM_QUIT, 0, 0 ); DosWaitThread( &sys->tid, DCWW_WAIT ); if( sys->pool ) picture_pool_Delete( sys->pool ); DosCloseEventSem( sys->ack_event ); free( sys ); }
// Все переменные - внешние. VOID ApplierKbdInputHook( HAB Application, PQMSG Message, PBYTE Discarding ) { // Запоминаем значения в окне ввода пароля. if( Applier.Settings.Script_after_Logon ) if( Applier.RTSettings.Logon_in_process ) { // Следим за нажатиями на клавиши. if( Message->msg == WM_CHAR ) { // Смотрим, какая клавиша нажата. BYTE Scan_code = CHAR4FROMMP( Message->mp1 ); SHORT State = SHORT1FROMMP( Message->mp1 ); // Если идет отжатие клавиши: if( State & KC_KEYUP ) { // Проверяем клавишу. BYTE Latin_key = 0; if( Scan_code != 0 ) if( !( State & KC_CTRL ) ) if( !( State & KC_ALT ) ) Latin_key = 1; // Если это латинская клавиша: if( Latin_key ) { // Узнаем окно рамки. HWND Frame_window = QueryFrameWindow( Message->hwnd ); // Если оно есть в списке отслеживаемых окон: for( INT Count = APPLIER_MONITORING_LOGON_WINDOWS - 1; Count >= 0; Count -- ) if( Applier.RTDlgMemory.Logon_windows[ Count ].Window == Frame_window ) { // Посылаем в очередь сообщение WM_MARK. Когда оно будет получено, окно подготовит значение в поле ввода. HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ ); WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_LOGON_VALUES, (MPARAM) Frame_window ); break; } } } } } // Возврат. return; }
// Frame_window - окно рамки, New_icon - новый значок. VOID Changer_ChangeWindowIcon( HWND Frame_window, HPOINTER New_icon ) { // Узнаем значок, который используется сейчас. HPOINTER Current_icon = (HPOINTER) WinSendMsg( Frame_window, WM_QUERYICON, 0, 0 ); // Меняем его. if( Current_icon != New_icon ) { // Задаем новый значок. WinSendMsg( Frame_window, WM_SETICON, (MPARAM) New_icon, 0 ); // Посылаем сообщение в поток рисования. WinPostQueueMsg( Enhancer.Modules.Painter->Message_queue, SM_DRAW_FRAME, (MPARAM) Frame_window, (MPARAM) WT_SYSMENU ); } // Возврат. return; }
// Message - сообщение, Scan_code - клавиша, Modifiers - клавиши Ctrl, Alt и Shift. // Post_marker_message означает, что в очередь окна надо направить сообщение WM_MARK. // Если переменная Message не задана - надо сбросить клавиши в исходное состояние. VOID KbdState_ChangePMKeyboardState( PQMSG Message, SHORT Scan_code, SHORT Modifiers, BYTE Post_marker_message = 1 ) { // Узнаем состояние клавиатуры. HWND Desktop = QueryDesktopWindow(); BYTE Keyboard_state[ 256 ]; bzero( Keyboard_state, sizeof( BYTE ) * 256 ); WinSetKeyboardStateTable( Desktop, Keyboard_state, 0 ); // Включаем или выключаем Ctrl, Alt и Shift. if( Message != NULL ) { if( Scan_code == SC_INSERT ) Keyboard_state[ VK_INSERT ] = SET_KEY_PRESSED; else Keyboard_state[ VK_INSERT ] = 0; if( Scan_code == SC_DELETE ) Keyboard_state[ VK_DELETE ] = SET_KEY_PRESSED; else Keyboard_state[ VK_DELETE ] = 0; if( Scan_code == SC_BACKSPACE ) Keyboard_state[ VK_BACKSPACE ] = SET_KEY_PRESSED; else Keyboard_state[ VK_BACKSPACE ] = 0; if( Modifiers & KC_CTRL ) Keyboard_state[ VK_CTRL ] = SET_KEY_PRESSED; else Keyboard_state[ VK_CTRL ] = 0; if( Modifiers & KC_ALT ) Keyboard_state[ KC_ALT ] = SET_KEY_PRESSED; else Keyboard_state[ KC_ALT ] = 0; if( Modifiers & KC_SHIFT ) Keyboard_state[ VK_SHIFT ] = SET_KEY_PRESSED; else Keyboard_state[ VK_SHIFT ] = 0; } // Или восстанавливаем настоящие значения. else { if( KeyIsPressed( SC_INSERT ) ) Keyboard_state[ VK_INSERT ] = SET_KEY_PRESSED; else Keyboard_state[ VK_INSERT ] = 0; if( KeyIsPressed( SC_DELETE ) ) Keyboard_state[ VK_DELETE ] = SET_KEY_PRESSED; else Keyboard_state[ VK_DELETE ] = 0; if( KeyIsPressed( SC_BACKSPACE ) ) Keyboard_state[ VK_BACKSPACE ] = SET_KEY_PRESSED; else Keyboard_state[ VK_BACKSPACE ] = 0; if( CtrlIsPressed() ) Keyboard_state[ VK_CTRL ] = SET_KEY_PRESSED; else Keyboard_state[ VK_CTRL ] = 0; if( AltIsPressed() ) Keyboard_state[ KC_ALT ] = SET_KEY_PRESSED; else Keyboard_state[ KC_ALT ] = 0; if( ShiftIsPressed() ) Keyboard_state[ VK_SHIFT ] = SET_KEY_PRESSED; else Keyboard_state[ VK_SHIFT ] = 0; } // Сбрасываем все сведения о кнопках мыши. Это необходимо при вставке текста с помощью // средней кнопки, когда сообщения сбрасываются, и данные, что кнопка нажата, остаются. Keyboard_state[ VK_BUTTON1 ] = 0; Keyboard_state[ VK_BUTTON2 ] = 0; Keyboard_state[ VK_BUTTON3 ] = 0; // Устанавливаем новое состояние клавиатуры. WinSetKeyboardStateTable( Desktop, Keyboard_state, 1 ); // Запоминаем, что состояние клавиатуры изменено. if( Message != NULL ) { // Запоминаем, что состояние клавиатуры изменено. KbdState.Keyboard_state_is_changed = 1; // Если в очередь окна надо направить сообщение: if( Post_marker_message ) { // Посылаем в очередь окна сообщение WM_MARK. Когда оно будет получено, состояние можно будет вернуть назад. HMQ Message_queue = WinQueryWindowULong( Message->hwnd, QWL_HMQ ); WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_KBD_MODIFIERS, 0 ); } } // Или запоминаем, что состояние клавиатуры восстановлено. else { // Запоминаем, что состояние клавиатуры восстановлено. KbdState.Keyboard_state_is_changed = 0; } // Возврат. return; }
void Draw_Thread(ULONG ulThreadArg) { if(!(habDT=WinInitialize(0UL))) /* Initialize client window */ GEN_ERR(habDT,hwndFrame,hwndClient); /* Create a message queue */ if(!(hmqDT=WinCreateMsgQueue(habDT,0UL))) GEN_ERR(habDT,hwndFrame,hwndClient); if(!(hpsDT=WinGetPS(hwndClient))) /* Get a presentation space for client area */ GEN_ERR(habDT,hwndFrame,hwndClient); /* Initialize message queue */ WinPostQueueMsg(hmqDT,DT_PAINT,0UL,0UL); while(qmsqDT.msg!=DT_EXIT) { if(WinPeekMsg(habDT, /* Get the message into message queue */ &qmsqDT, /* Message structure */ NULLHANDLE, /* Window filter (none) */ 0UL, /* First message ID */ 0UL, /* Last message ID */ PM_REMOVE)==FALSE) /* Options (remove message) */ qmsqDT.msg=DT_IDLE; /* If no message available, assume idle */ switch(qmsqDT.msg) { case DT_PAINT: /* Repaint client window */ { RECTL rclDT; int x,y; /* Repaint client window aread */ WinQueryWindowRect(hwndClient,&rclDT); WinFillRect(hpsDT,&rclDT,CLR_WHITE); for(x=1;x<RB_X;x++) /* Draw the entries on playing ground */ for(y=1;y<RB_Y;y++) if(RB_Array[x][y]!=RB_EMPTY) Draw_Bitmap(RB_Array[x][y],ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE); break; } case DT_LBUTTON: { int x,y; /* Left button was pressed, get the location, add \ to RB_Array, and draw \ bitmap, if field is emty */ x=(LONGFROMMP(qmsqDT.mp1)/RB_SIZE)+1; y=(LONGFROMMP(qmsqDT.mp2)/RB_SIZE)+1; if(RB_Array[x][y]==RB_EMPTY) { RB_Array[x][y]=RB_LX; Draw_Bitmap(RB_LX,ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE); } break; } case DT_RBUTTON: { int x,y; /* Right button was pressed, get the location, add / to RB_Array, and draw / bitmap, if field is emty */ x=(LONGFROMMP(qmsqDT.mp1)/RB_SIZE)+1; y=(LONGFROMMP(qmsqDT.mp2)/RB_SIZE)+1; if(RB_Array[x][y]==RB_EMPTY) { RB_Array[x][y]=RB_RX; Draw_Bitmap(RB_RX,ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE); } break; } case DT_IDLE: { if(runRB==TRUE) { ULONG x,y,Symbol; /* Under DOS we would query the time in milliseconds from the system timer, to adjust graphics. This is accurate, but in a multitasking in a multitasking system, we must assume being pre-empted. Therefore we can't have an exact time bases. Hope that the system timer counts more often than all 31 milliseconds in future releases/machines */ /* Draw bitmap */ switch(RB_Dir) /* Test that RollBall doesn't leave borders. A border reverses the direction and produces a beep */ { case UP: RB_PosY++; if((RB_PosY+RB_SIZE)>=((RB_Y-2)*RB_SIZE)) { RB_PosY=(RB_Y-3)*RB_SIZE; RB_Dir=DOWN; DosBeep(800,50); } break; case DOWN: RB_PosY--; if(RB_PosY<0) { RB_PosY=0; RB_Dir=UP; DosBeep(800,50); } break; case LEFT: RB_PosX--; if(RB_PosX<0) { RB_PosX=0; RB_Dir=RIGHT; DosBeep(800,50); } break; case RIGHT: RB_PosX++; if((RB_PosX+RB_SIZE)>=((RB_X-2)*RB_SIZE)) { RB_PosX=(RB_X-3)*RB_SIZE; RB_Dir=LEFT; DosBeep(800,50); } break; } /* Draw RollBall at new position */ Draw_Bitmap(RB_RB,ROP_SRCCOPY,RB_PosX,RB_PosY); /* Now, test if the middle of RollBall is over any symbol. If a symbol is found, add points, deflect or end game */ /* RB_Array is 1 based, because 0 indices are the playing ground borders */ x=((RB_PosX)/RB_SIZE)+1; y=((RB_PosY)/RB_SIZE)+1; /* A Symbol if RB_SIZE*RB_SIZE in size, that means RollBall is exactly over a symbol, if the lower left edges of both symbols match. Then, and only then, we count points, deflect or loose */ if((RB_PosX==(x-1)*RB_SIZE) && (RB_PosY==(y-1)*RB_SIZE)) Symbol=RB_Array[x][y]; else Symbol=RB_EMPTY; switch(Symbol) { case RB_LX: /* We got a \ deflector */ { switch(RB_Dir) /* \ deflects direction of RollBall */ { case RIGHT: RB_Dir=DOWN; break; case UP: RB_Dir=LEFT; break; case LEFT: RB_Dir=UP; break; case DOWN: RB_Dir=RIGHT; break; } /* Remove deflector */ RB_Array[x][y]=RB_EMPTY; break; } case RB_RX: /* We got a / deflector */ { switch(RB_Dir) /* / deflects direction of RollBall */ { case RIGHT: RB_Dir=UP; break; case UP: RB_Dir=RIGHT; break; case LEFT: RB_Dir=DOWN; break; case DOWN: RB_Dir=LEFT; break; } /* Remove deflector */ RB_Array[x][y]=RB_EMPTY; DosBeep(600,20); break; } case RB_BP: /* We got a point */ case RB_GP: case RB_MP: case RB_VP: { /* Add the points for each symbol */ RB_Point[0]+=RB_Point[Symbol]; /* Remove the point */ RB_Array[x][y]=RB_EMPTY; if (ulDelay) ulDelay--; DosBeep(700,20); break; } case RB_HOLE: /* We got a hole, sorry but RollBall will be killed. We disable RollBall from rolling, and send a ID_STOPTHREAD message to our window, which informs the user about the points with a message box */ { int freq; for(freq=5000;freq>100;freq-=100) DosBeep(freq,5); runRB=FALSE; /* Prevent RollBall from further rolling */ WinPostMsg(hwndClient,WM_COMMAND,(MPARAM)ID_STOPTHREAD,(MPARAM)0); break; } } /* Randomly add and remove symbols on playing ground */ if((rand()%500)<2) { Put_Random_Field(); Clear_Random_Field(); } } } } DosOpen("TIMER0$", &hfile, &ulAction, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE, NULL); ulDelay2=ulDelay/2; DosDevIOCtl(hfile, HRT_IOCTL_CATEGORY, HRT_BLOCKUNTIL, &ulDelay2, ulSize2, &ulSize2, NULL, 0, NULL); DosClose(hfile); } WinReleasePS(hpsDT); /* Clean up */ WinDestroyMsgQueue(hmqDT); WinTerminate(habDT); DosExit(EXIT_THREAD,0UL); }
BOOL ChangeWPS(PCHAR pszUserIni, PCHAR pszSystemIni) { PCHAR pcEnv; PRFPROFILE prfProfile; BOOL bSuccess; if (*pszSystemIni == '\0') prfProfile.pszSysName = pShareInitOS2->pszRootSystemIni; else prfProfile.pszSysName = pszSystemIni; if (*prfProfile.pszSysName == '\0') prfProfile.pszSysName = (DosScanEnv (ENV_SYSTEM_INI, &pcEnv) ? "" : pcEnv); if (*pszUserIni == '\0') { prfProfile.pszUserName = pShareInitOS2->pszRootUserIni; pShareInitOS2->ulFlag = pShareInitOS2->ulFlag_Root; // ulFlag f�r Rootdesktop } else prfProfile.pszUserName = pszUserIni; if (*prfProfile.pszUserName == '\0') prfProfile.pszUserName = (DosScanEnv (ENV_USER_INI, &pcEnv) ? "" : pcEnv); prfProfile.cchUserName = strlen(prfProfile.pszUserName); prfProfile.cchSysName = strlen(prfProfile.pszSysName); if (ulOldFlag & CLOSEAPPL) WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "WORKAREA=YES"); else WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "WORKAREA=NO"); WinPostMsg(WinQueryWindow(HWND_DESKTOP, QW_BOTTOM), WM_CLOSE, 0, 0); DebugS (1, "HWND_DESKTOP closed"); if( hevPrfResetLock ) { DosWaitEventSem (hevPrfResetLock, SEM_INDEFINITE_WAIT); DosSleep(1000); DebugS (1, "hevPrfResetLock released"); } else DosSleep(20000); bSuccess = PrfReset(hab, &prfProfile); DebugULd (1, "PrfReset", "return", bSuccess); /* * Beim Umschalten auf den Root, egal ob von Sammy oder von WPSamF ausgel�st, * wird die Shell vom PrfReset nicht geschlossen. * Solange die Ursache nicht bekannt ist, bleibt nichts anderes �brig, * als an dieser Stelle symptomatisch vorzugehen und die Shell abzuschie�en. */ if (*pszUserIni == '\0') { DosSuspendThread (tid1); DosKillProcess( DKP_PROCESSTREE, ulShellID ); // sog. Budnik'scher Arschtritt DebugS (1, "Shell killed"); DosResumeThread (tid1); } if( !bSuccess ) { WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "OPEN=ICON;WORKAREA=YES"); DebugS (1, "Desktop set to <WP_DESKTOP>"); intSammyRetCode = 250; WinPostQueueMsg (hmq, WM_QUIT, 0L, 0L); } else ulOldFlag = pShareInitOS2->ulFlag; return( bSuccess ); }
ULONG ulExecProg (CHAR *szProgName) { ULONG ulBootDrive; ULONG ulAppType; CHAR szCmdName[CCHMAXPATH]; CHAR szLine[CCHMAXPATH]; PSZ pszScanEnv; RESULTCODES rcTermination; APIRET rcFailure = 0; PCHAR pszEnvironment; /* * Diese Routine versucht eine Shell zu starten. */ pszEnvironment = MakeEnv (pShareInitOS2->pszEnvironment); if ( !(rcFailure = ScanEnv(ENV_SAMWORKPLACE, &pszScanEnv, pszEnvironment)) ) { rcFailure = DosQueryAppType(pszScanEnv, &ulAppType); if ( !rcFailure ) if ( ( (ulAppType & 7) == FAPPTYP_NOTSPEC) || ( (ulAppType & 7) == FAPPTYP_WINDOWAPI) ) rcFailure = DosExecPgm (szLine, /* Object name buffer */ sizeof(szLine), /* Length of object name buffer */ EXEC_ASYNCRESULT, /* Execution flags */ "", /* Argument string */ pszEnvironment, /* Environment */ &rcTermination, /* Termination codes */ pszScanEnv); /* Program file name */ else rcFailure = 1; } if (rcFailure) { WinAlarm (HWND_DESKTOP, WA_ERROR); DebugS (1, "DosExecPgm <1> failed"); } if (rcFailure) { rcFailure = DosExecPgm (szLine, /* Object name buffer */ sizeof(szLine), /* Length of object name buffer */ EXEC_ASYNCRESULT, /* Execution flags */ "", /* Argument string */ pszEnvironment, /* Environment */ &rcTermination, /* Termination codes */ szProgName); /* Program file name */ } if (rcFailure) { if (!(rcFailure = DosScanEnv (ENV_SAMWORKPLACE, &pszScanEnv))) rcFailure = DosExecPgm (szLine, /* Object name buffer */ sizeof(szLine), /* Length of object name buffer */ EXEC_ASYNCRESULT, /* Execution flags */ "", /* Argument string */ pszEnvironment, /* Environment */ &rcTermination, /* Termination codes */ pszScanEnv); /* Program file name */ } if (rcFailure) { DebugS (1, "DosExecPgm <2> failed"); DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ULONG)); memset (szCmdName, '\0', sizeof(szCmdName)); szCmdName[0] = (CHAR) (ulBootDrive - 1) + 'A'; strcpy (szCmdName+1, ":\\OS2\\PMSHELL.EXE"); rcFailure = DosExecPgm (szLine, /* Object name buffer */ sizeof(szLine), /* Length of object name buffer */ EXEC_ASYNCRESULT, /* Execution flags */ "", /* Argument string */ pszEnvironment, /* Environment */ &rcTermination, /* Termination codes */ szCmdName); /* Program file name */ } /* Falls Shell nicht gestartet werden konnte, wird cmd.exe aufgerufen */ if (rcFailure) { DebugS (1, "DosExecPgm <3> failed"); if (!(rcFailure = DosScanEnv ("COMSPEC", &pszScanEnv))) rcFailure = DosExecPgm (szLine, /* Object name buffer */ sizeof(szLine), /* Length of object name buffer */ EXEC_ASYNCRESULT, /* Execution flags */ "/K", /* Argument string */ pszEnvironment, /* Environment */ &rcTermination, /* Termination codes */ pszScanEnv); /* Program file name */ } if (rcFailure) { DebugS (1, "DosExecPgm <4> failed"); DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ULONG)); memset (szCmdName, '\0', sizeof(szCmdName)); szCmdName[0] = (CHAR) (ulBootDrive - 1) + 'A'; strcpy (szCmdName+1, ":\\OS2\\CMD.EXE"); rcFailure = DosExecPgm (szLine, /* Object name buffer */ sizeof(szLine), /* Length of object name buffer */ EXEC_ASYNCRESULT, /* Execution flags */ "/K", /* Argument string */ pszEnvironment, /* Environment */ &rcTermination, /* Termination codes */ szCmdName); /* Program file name */ } DosFreeMem(pszEnvironment); if (rcFailure) { intSammyRetCode = rcFailure; WinPostQueueMsg (hmq, WM_CLOSE, 0L, 0L); DebugS (1, "DosExecPgm <5> failed"); } return (rcFailure ? 0 : rcTermination.codeTerminate); }
// Frame_window - окно рамки, Target и Buttons_to_detect - какое свойство надо узнать. // Update_frame_if_required - рамку можно обновить если это требуется. VOID Diver_QueryWindowProperty( HWND Frame_window, ULONG Target, LONG Buttons_to_detect = ALL_ACTIONS, BYTE Update_frame_if_required = 0 ) { // Узнаем расположение окна и его состояние. SWP Window_state = {0}; WinQueryWindowPos( Frame_window, &Window_state ); // Если окно уменьшено в значок или скрыто - возврат. if( Window_state.fl & SWP_MINIMIZE || Window_state.fl & SWP_HIDE ) return; // Узнаем значок окна. if( Target & WT_SYSMENU ) { // Узнаем значок окна. HPOINTER Icon = Diver_QueryWindowIcon( Frame_window ); // Если он есть: if( Icon != NULLHANDLE ) { // Если значок изменился - рамка должна быть перерисована. HPOINTER Previous_icon = NULLHANDLE; FindProperty( Frame_window, PRP_ICON, &Previous_icon ); if( Icon != Previous_icon ) { // Устанавливаем свойство. SetProperty( Frame_window, PRP_ICON, &Icon ); // Посылаем сообщение в поток рисования. WinPostQueueMsg( Enhancer.Modules.Painter->Message_queue, SM_DRAW_FRAME, (MPARAM) Frame_window, (MPARAM) WT_SYSMENU ); } } } // Узнаем ширину рамки окна. if( Target & WT_SYSMENU ) { // Отправляем сообщение в окно. Diver.RTSettings.FB_size.x = 0; Diver.RTSettings.FB_size.y = 0; WinSendMsg( Frame_window, WM_QUERYBORDERSIZE, (MPARAM) &Diver.RTSettings.FB_size, 0 ); // Шириной рамки будем считать наименьшее полученное значение. INT Width = min( Diver.RTSettings.FB_size.x, Diver.RTSettings.FB_size.y ); // Если оно было получено: if( Width != 0 ) { // Если ширина изменилась - рамка должна быть перерисована. INT Previous_width = 0; FindProperty( Frame_window, PRP_BORDER, &Previous_width ); if( Width != Previous_width ) { // Устанавливаем свойство. SetProperty( Frame_window, PRP_BORDER, &Width ); // Узнаем значение по умолчанию. INT System_value = FrameWidth( Frame_window ); // Если это другое значение - посылаем сообщение в поток рисования. if( Width != System_value ) { ULONG Update_all = WT_BORDER | WT_SYSMENU | WT_TITLEBAR | WT_MINMAX | WT_MENU; WinPostQueueMsg( Enhancer.Modules.Painter->Message_queue, SM_DRAW_FRAME, (MPARAM) Frame_window, (MPARAM) Update_all ); } } } } // Узнаем заголовок окна. if( Target & WT_TITLEBAR ) { // Узнаем заголовок окна. HWND TitleBar_window = WinWindowFromID( Frame_window, FID_TITLEBAR ); CHAR Title[ SIZE_OF_TITLE ] = ""; QueryWindowTitle( Frame_window, TitleBar_window, Title, Update_frame_if_required ); // Если заголовок определен: if( Title[ 0 ] != 0 ) { // Если заголовок изменился - рамка должна быть перерисована. CHAR Previous_title[ SIZE_OF_TITLE ] = ""; FindProperty( Frame_window, PRP_TITLE, Previous_title ); if( !strc( Title, Previous_title ) ) { // Устанавливаем свойство. SetProperty( Frame_window, PRP_TITLE, Title ); // Посылаем сообщение в поток рисования. WinPostQueueMsg( Enhancer.Modules.Painter->Message_queue, SM_DRAW_FRAME, (MPARAM) Frame_window, (MPARAM) WT_TITLEBAR ); } } } // Узнаем состояние кнопок в правом верхнем углу окна. if( Target & WT_MINMAX ) { // Узнаем, есть ли это свойство в списке. BYTE Actions_are_detected = 0; FindProperty( Frame_window, PRP_ACTIONS, &Actions_are_detected ); // Если его нет - узнаем состояние кнопок по умолчанию. if( !Actions_are_detected ) { // Узнаем состояние кнопок по умолчанию. LONG Buttons_state = Diver_GetPreDefinedButtonsState( Frame_window ); // Запоминаем, что состояние кнопок определено. BYTE Detected = 1; SetProperty( Frame_window, PRP_ACTIONS, &Detected ); // Если оно задано - рамка должна быть перерисована. if( Buttons_state != NO_ACTION ) { // Устанавливаем свойство. SetProperty( Frame_window, PRP_BUTTONS, &Buttons_state ); // Посылаем сообщение в поток рисования. WinPostQueueMsg( Enhancer.Modules.Painter->Message_queue, SM_DRAW_FRAME, (MPARAM) Frame_window, (MPARAM) WT_BORDER ); } } // Узнаем состояние кнопок в окне. LONG Buttons_state = QueryButtonsState( Frame_window, Buttons_to_detect, 1 ); // Если состояние кнопок изменилось - рамка должна быть перерисована. LONG Previous_state = NO_ACTION; FindProperty( Frame_window, PRP_BUTTONS, &Previous_state ); if( Buttons_state != Previous_state ) { // Устанавливаем свойство. SetProperty( Frame_window, PRP_BUTTONS, &Buttons_state ); // Посылаем сообщение в поток рисования. WinPostQueueMsg( Enhancer.Modules.Painter->Message_queue, SM_DRAW_FRAME, (MPARAM) Frame_window, (MPARAM) WT_BORDER ); } } // Возврат. return; }
VOID gropFree(PGROPDATA pGrop) { ULONG ulRC; HMQ hmq; TID tid; ulRC = DosRequestMutexSem( pGrop->hmtxData, 4000 ); if ( ulRC != NO_ERROR ) debug( "DosRequestMutexSem(), rc = %u", ulRC ); hmq = pGrop->hmq; tid = pGrop->tid; // Tune off all callback functions. memset( &pGrop->stCallback, 0, sizeof(GROPCALLBACK) ); DosReleaseMutexSem( pGrop->hmtxData ); if ( ( hmq == NULLHANDLE ) || !WinPostQueueMsg( hmq, WM_QUIT, 0, 0 ) ) { debug( "Hm... have not a thread?..." ); if ( pGrop->fFullscreen ) _setMode( pGrop, pGrop->ulModeIdx, FALSE ); if ( tid != ((TID)(-1)) ) { debug( "WTF?! %p %d", pGrop, tid ); DosKillThread( tid ); } } else if ( DosWaitThread( &tid, DCWW_NOWAIT ) != NO_ERROR ) { debug( "Wait thread semaphore" ); ulRC = DosWaitEventSem( pGrop->hevReady, 4000 ); if ( ulRC != NO_ERROR ) { PVIDEOMODE pMode = &pGrop->stModes.pList[pGrop->stModes.ulDesktopMode]; debug( "DosWaitEventSem(), rc = %u. Kill thread...", ulRC ); DosKillThread( tid ); if ( pGrop->hwndDT != NULLHANDLE ) { debug( "Return to the desktop..." ); pGrop->pVideoSys->fnSetMode( pGrop->pVSData, pMode, FALSE, pGrop->hwndDT, pGrop->hdcDT ); } } else { debug( "Wait thread" ); DosWaitThread( &tid, DCWW_WAIT ); } } else debug( "Thread already terminated." ); // Remove GROP object from the list. ulRC = DosRequestMutexSem( hmtxGropList, SEM_INDEFINITE_WAIT ); if ( ulRC != NO_ERROR ) debug( "DosRequestMutexSem(), rc = %u", ulRC ); lnkseqRemove( &lsGropList, pGrop ); DosReleaseMutexSem( hmtxGropList ); DosCloseEventSem( pGrop->hevReady ); debugFree( pGrop ); debug( "Success." ); }
void OS2Loop::exit() { WinPostQueueMsg( HMQ_CURRENT, WM_QUIT, 0, 0 ); }
// Frame_window - окно рамки. HPOINTER Diver_QueryWindowIcon( HWND Frame_window ) { // Для некоторых окон есть значки по умолчанию, но устанавливать их нельзя. if( IsEPMEditorWindow( Frame_window ) || WindowIsCreatedBy( APP_EPM, Frame_window ) ) { if( Diver.RTSettings.EPM_icon == NULLHANDLE ) { ULONG Boot_drive = 0; DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, (PULONG) &Boot_drive, sizeof( Boot_drive ) ); if( Boot_drive ) { CHAR Path[ SIZE_OF_PATH ] = "*:"; Path[ 0 ] = (CHAR) Boot_drive + 64; strcat( Path, "\\OS2\\Apps\\Epm.exe" ); if( FileExists( Path ) ) Diver.RTSettings.EPM_icon = WinLoadFileIcon( Path, 0 ); } } if( Diver.RTSettings.EPM_icon != NULLHANDLE ) return Diver.RTSettings.EPM_icon; else return Resources.Default_icons[ ICON_VIEWDOC ]; } // Для некоторых окон значки по умолчанию можно установить раз и навсегда, отправив сообщение в окно. HPOINTER Icon = NULLHANDLE; if( Icon == NULLHANDLE ) { if( IsWinListWindow( Frame_window ) ) Icon = Resources.Default_icons[ ICON_WINLIST ]; } if( Icon == NULLHANDLE ) { if( WindowIsCreatedBy( APP_VIEWDOC, Frame_window ) ) Icon = Resources.Default_icons[ ICON_VIEWDOC ]; } if( Icon == NULLHANDLE ) { if( WindowIsCreatedBy( APP_PMCHKDSK, Frame_window ) ) { if( Diver.RTSettings.HDD_icon == NULLHANDLE ) { ULONG Boot_drive = 0; DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, (PULONG) &Boot_drive, sizeof( Boot_drive ) ); if( Boot_drive ) { CHAR Path[ SIZE_OF_PATH ] = "*:"; Path[ 0 ] = (CHAR) Boot_drive + 64; strcat( Path, "\\eCS\\Bin\\PMFormat.exe" ); if( FileExists( Path ) ) Diver.RTSettings.HDD_icon = WinLoadFileIcon( Path, 0 ); } } if( Diver.RTSettings.HDD_icon == NULLHANDLE ) { CHAR Path[ SIZE_OF_PATH ] = ""; HOBJECT WPDrives_object = QueryWPSObject( "<WP_DRIVES>" ); if( WPDrives_object != NULLHANDLE ) WinQueryObjectPath( WPDrives_object, Path, SIZE_OF_PATH ); if( Path[ 0 ] != 0 ) Diver.RTSettings.HDD_icon = WinLoadFileIcon( Path, 0 ); } if( Diver.RTSettings.HDD_icon != NULLHANDLE ) Icon = Diver.RTSettings.HDD_icon; } } if( Icon == NULLHANDLE ) { if( WindowIsCreatedBy( APP_APPLETVIEWER, Frame_window ) ) { HWND Related_window = FindRelatedFrameWindow( Frame_window, &IsHotJavaBrowserWindow ); if( Related_window != NULLHANDLE ) { Icon = (HPOINTER) WinSendMsg( Related_window, WM_QUERYICON, 0, 0 ); } } } // Если значок был выбран - ставим и возвращаем его. if( Icon != NULLHANDLE ) { if( DrawSystemMenusSettingIsON() ) { WinPostQueueMsg( Enhancer.Modules.Changer->Message_queue, SM_CHANGE_ICON, (MPARAM) Frame_window, (MPARAM) Icon ); } return Icon; } // Узнаем значок окна. Icon = (HPOINTER) WinSendMsg( Frame_window, WM_QUERYICON, 0, 0 ); // Если это пустой значок - ставим изображение по умолчанию. HWND Desktop = QueryDesktopWindow(); if( Icon == WinQuerySysPointer( Desktop, SPTR_APPICON, 0 ) ) { Icon = WinQuerySysPointer( Desktop, SPTR_PROGRAM, 0 ); if( DrawSystemMenusSettingIsON() ) { WinPostQueueMsg( Enhancer.Modules.Changer->Message_queue, SM_CHANGE_ICON, (MPARAM) Frame_window, (MPARAM) Icon ); } return Icon; } // Если значок неизвестен - возвращаем значок владельца, главного окна, или значок по умолчанию. // Менять значок во всех случаях нельзя - может возникнуть постоянное рисование, которое выглядит как "мигание" рамки. if( Icon == NULLHANDLE ) { // Узнаем окно рабочего стола. HWND Desktop = QueryDesktopWindow(); // Просматриваем всех владельцев. HWND Owner_window = WinQueryWindow( Frame_window, QW_FRAMEOWNER ); while( Owner_window != Desktop && Owner_window != NULLHANDLE ) { // Если владелец - окно рамки: if( IsFrameWindow( Owner_window ) ) { // Узнаем его значок. Icon = (HPOINTER) WinSendMsg( Owner_window, WM_QUERYICON, 0, 0 ); // Если он есть - возвращаем его. if( Icon != NULLHANDLE ) return Icon; } // Узнаем следующего владельца. Owner_window = WinQueryWindow( Owner_window, QW_FRAMEOWNER ); } // Узнаем главное окно приложения. HWND Main_window = QueryMainWindow( Frame_window ); // Если это другое окно: if( Main_window != Frame_window ) { // Узнаем его значок. Icon = (HPOINTER) WinSendMsg( Main_window, WM_QUERYICON, 0, 0 ); // Если он есть - возвращаем его. if( Icon != NULLHANDLE ) return Icon; } // Узнаем очередь сообщений окна. HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ ); // Узнаем окно оболочки. HWND Shell_window = GetDetectedShellWindow(); if( Shell_window != NULLHANDLE ) { // Узнаем очередь сообщений для окна оболочки. HMQ Shell_queue = WinQueryWindowULong( Shell_window, QWL_HMQ ); // Если очереди совпадают - возвращаем его значок. if( Shell_queue == Message_queue ) return (HPOINTER) WinSendMsg( Shell_window, WM_QUERYICON, 0, 0 ); // Если еще как-нибудь можно установить, что окно создано оболочкой - возвращаем значок окна оболочки. if( IsWorkplaceShellWindow( Frame_window ) ) return (HPOINTER) WinSendMsg( Shell_window, WM_QUERYICON, 0, 0 ); } { // Перебираем окна в окне рабочего стола. HENUM Enumeration = WinBeginEnumWindows( Desktop ); HWND Window = NULLHANDLE; while( ( Window = WinGetNextWindow( Enumeration ) ) != NULLHANDLE ) { // Если это то же самое окно - продолжаем перебор окон. if( Window == Frame_window ) continue; // Узнаем расположение окна и его состояние. SWP Window_state = {0}; WinQueryWindowPos( Window, &Window_state ); // Если окно не скрыто и не уменьшено в значок: if( !( Window_state.fl & SWP_HIDE ) ) if( !( Window_state.fl & SWP_MINIMIZE ) ) { // Если в это окно нельзя переключиться - продолжаем перебор окон. if( !PermissionForSwitching( Window ) ) continue; } // Узнаем очередь сообщений окна. HMQ Window_queue = WinQueryWindowULong( Window, QWL_HMQ ); // Если очереди совпадают - узнаем его значок. if( Window_queue == Message_queue ) { // Узнаем значок окна. Icon = (HPOINTER) WinSendMsg( Window, WM_QUERYICON, 0, 0 ); // Если он есть - возвращаем его. if( Icon != NULLHANDLE ) { // Завершаем перебор окон. WinEndEnumWindows( Enumeration ); // Возвращаем значок. return Icon; } } } WinEndEnumWindows( Enumeration ); } // Узнаем путь к приложению, создавшему окно. CHAR Path[ SIZE_OF_PATH ] = ""; GetDetectedExePath( Frame_window, Path ); // Если его удалось определить: if( Path[ 0 ] != 0 ) { // Узнаем имя приложения, создавшего окно. CHAR Name[ SIZE_OF_PATH ] = ""; GetDetectedExeName( Frame_window, Name ); // Составляем полный путь. strcat( Path, "\\" ); strcat( Path, Name ); // Загружаем значок для файла приложения. Icon = WinLoadFileIcon( Path, 0 ); // Загрузка длится долго, поэтому в этом случае надо заменить значок окна. При // повторной загрузке возможна утечка памяти, так что лучше сделать это немедленно, // не посылая сообщений в поток Changer. WinSendMsg( Frame_window, WM_SETICON, (MPARAM) Icon, 0 ); // Запоминаем, что значок был загружен с диска. BYTE Icon_was_loaded = 1; SetProperty( Frame_window, PRP_ICON_WAS_LOADED, &Icon_was_loaded ); // Возвращаем значок. return Icon; } // Для окон постоянного размера выбираем простой значок. if( WindowIsDialog( Frame_window ) ) { return Resources.Default_icons[ ICON_LEAF ]; } // Для остальных окон - он зависит от того, можно ли переключиться в окно. else { HSWITCH Switch_handle = WinQuerySwitchHandle( Frame_window, NULLHANDLE ); if( Switch_handle != NULLHANDLE ) return Resources.Default_icons[ ICON_LEAVES ]; else return Resources.Default_icons[ ICON_LEAF ]; } // И наконец, значок мог быть задан в свойствах раньше. FindProperty( Frame_window, PRP_ICON, &Icon ); } // Возврат. return Icon; }
// Все переменные - внешние. VOID RoomsKbdInputHook( HAB Application, PQMSG Message, PBYTE Discarding ) { // Если надо добавить комнаты к рабочему столу: if( Rooms.Settings.Create_Rooms ) { // Переходим в другую комнату при нажатии на цифровые клавиши. Посылаем сообщение в поток и сбрасываем пришедшее сообщение. if( Rooms.Settings.Switch_by_keyboard ) if( Message->msg == WM_CHAR ) { // Смотрим, какая клавиша нажата. BYTE Scan_code = CHAR4FROMMP( Message->mp1 ); SHORT State = SHORT1FROMMP( Message->mp1 ); // Если идет нажатие клавиши: if( !( State & KC_KEYUP ) ) if( !( State & KC_PREVDOWN ) ) { // Узнаем, в какую комнату надо перейти. INT Room = 0; // Должна быть нажата клавиша Shift и цифровая клавиша. if( State & KC_SHIFT ) if( ShiftIsPressed() ) { if( Scan_code == SC_NUM_5 ) Room = SHELL_ROOM; if( Scan_code == SC_NUM_8 ) Room = NORTHERN_ROOM; if( Scan_code == SC_NUM_4 ) Room = WESTERN_ROOM; if( Scan_code == SC_NUM_6 ) Room = EASTERN_ROOM; if( Scan_code == SC_NUM_2 ) Room = SOUTHERN_ROOM; if( Scan_code == SC_NUM_7 || Scan_code == SC_NUM_9 || Scan_code == SC_NUM_1 || Scan_code == SC_NUM_3 ) Room = CURRENT_ROOM; } // Если вызвана заставка - действие выполнять не надо. if( Room ) if( SystemIsLocked() ) { Room = 0; *Discarding = 1; } // Если надо переключиться в другую комнату: if( Room ) { // Посылаем сообщение в поток. if( Room != CURRENT_ROOM ) WinPostQueueMsg( Enhancer.Modules.Rooms->Message_queue, SM_GO_TO_ROOM, (MPARAM) Room, 0 ); // Сообщение должно быть сброшено. *Discarding = 1; } } } // Добиваемся правильной работы потоков после перехода между комнатами. if( Rooms.Settings.Synchronize_arranger_and_rooms ) { // Если была нажата любая клавиша - считаем, что смена комнат завершена. if( Message->msg == WM_CHAR ) { // Смотрим, какая клавиша нажата. BYTE Scan_code = CHAR4FROMMP( Message->mp1 ); SHORT State = SHORT1FROMMP( Message->mp1 ); // Если идет нажатие клавиши: if( !( State & KC_KEYUP ) ) if( !( State & KC_PREVDOWN ) ) { // Если эта клавиша не используется дл переключения между комнатами - смена комнат завершена. if( Scan_code < SC_NUM_FIRST || Scan_code > SC_NUM_LAST ) Rooms.Settings.Synchronize_arranger_and_rooms = 0; } } } } // Возврат. return; }
// Все переменные - внешние. VOID RoomsInputHook( HAB Application, PQMSG Message, PBYTE Discarding ) { // Если надо добавить комнаты к рабочему столу: if( Rooms.Settings.Create_Rooms ) { // Переходим в другую комнату при получении сообщения WM_MARK. if( Rooms.Settings.Switch_by_WarpCenter ) if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_GO_TO_ROOM ) { // Узнаем, в какую комнату надо перейти. LONG Scan_code = (LONG) Message->mp2; INT Room = 0; if( Scan_code == SC_NUM_5 ) Room = SHELL_ROOM; if( Scan_code == SC_NUM_8 ) Room = NORTHERN_ROOM; if( Scan_code == SC_NUM_4 ) Room = WESTERN_ROOM; if( Scan_code == SC_NUM_6 ) Room = EASTERN_ROOM; if( Scan_code == SC_NUM_2 ) Room = SOUTHERN_ROOM; if( Scan_code == SC_NUM_7 || Scan_code == SC_NUM_9 || Scan_code == SC_NUM_1 || Scan_code == SC_NUM_3 ) Room = CURRENT_ROOM; // Если вызвана заставка - действие выполнять не надо. if( Room ) if( SystemIsLocked() ) { Room = 0; *Discarding = 1; } // Если надо переключиться в другую комнату: if( Room ) { // Посылаем сообщение в поток. if( Room != CURRENT_ROOM ) WinPostQueueMsg( Enhancer.Modules.Rooms->Message_queue, SM_GO_TO_ROOM, (MPARAM) Room, 0 ); // Сообщение должно быть сброшено. *Discarding = 1; } } // Закрашиваем окно рабочего стола. if( Rooms.Settings.Draw_wallpaper ) { // Если окно должно быть перерисовано и это рабочий стол: if( Message->msg == WM_PAINT ) if( Message->hwnd == QueryDesktopWindow() ) { // Посылаем в очередь окна сообщение WM_MARK. Когда оно будет получено, окно можно будет закрасить. HMQ Message_queue = WinQueryWindowULong( Message->hwnd, QWL_HMQ ); WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_FILL_DESKTOP, (MPARAM) Message->hwnd ); } // Обрабатываем сообщение WM_MARK. if( Message->hwnd == NULLHANDLE ) if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_FILL_DESKTOP ) { HWND Window = (HWND) Message->mp2; if( Window == QueryDesktopWindow() ) { // Посылаем сообщение в поток. WinPostQueueMsg( Enhancer.Modules.Rooms->Message_queue, SM_FILL_DESKTOP, (MPARAM) Window, 0 ); } } } // Вызываем LaunchPad или список окон при нажатии кнопок мыши в окне рабочего стола. BYTE Show_LaunchPad = 0; BYTE Show_Window_list = 0; BYTE Hide_Window_list = 0; // Если левая кнопка мыши нажата дважды - вызываем LaunchPad. if( Message->msg == WM_BUTTON1DBLCLK ) if( Message->hwnd == QueryDesktopWindow() ) Show_LaunchPad = 1; // Если она нажата один раз: if( Message->msg == WM_BUTTON1DOWN ) { // Узнаем окно рабочего стола. HWND Desktop = QueryDesktopWindow(); // Если мышь нажата в окне рабочего стола - проверяем состояние других кнопок мыши. if( Message->hwnd == Desktop ) { if( MouseButtonIsPressed( 2 ) || MouseButtonIsPressed( 3 ) ) Show_Window_list = 1; else Hide_Window_list= 1; } } // Если нажата правая или средняя кнопка: if( Message->msg == WM_BUTTON2DOWN || Message->msg == WM_BUTTON3DOWN ) { // Узнаем окно рабочего стола. HWND Desktop = QueryDesktopWindow(); // Если мышь нажата в окне рабочего стола - проверяем состояние левой кнопки мыши. if( Message->hwnd == Desktop ) { if( MouseButtonIsPressed( 1 ) ) Show_Window_list = 1; else Hide_Window_list = 1; } } // Если надо вызвать LaunchPad или список окон - посылаем сообщение в поток. if( Show_LaunchPad ) WinPostQueueMsg( Enhancer.Modules.Launcher->Message_queue, SM_SHOW_LAUNCHPAD, 0, 0 ); if( Show_Window_list ) WinPostQueueMsg( Enhancer.Modules.Launcher->Message_queue, SM_SHOW_WINDOW_LIST, (MPARAM) 1, 0 ); if( Hide_Window_list ) { WinPostQueueMsg( Enhancer.Modules.Launcher->Message_queue, SM_HIDE_WINDOW_LIST, 0, 0 ); WinPostQueueMsg( Enhancer.Modules.Launcher->Message_queue, SM_HIDE_WARPCENTER, 0, 0 ); } // Если используется оболочка WPS: if( ShellIsWPS() ) { // Проверяем окно WPS, которое становится выбранным, чтобы скрыть окно оболочки. // Это сообщение посылается в окно в SendMsgHook() при обработке сообщения WM_ACTIVATE. if( GetCurrentOrNextRoom() != SHELL_ROOM ) if( Message->hwnd == NULLHANDLE ) if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_CHECK_WINDOW ) { // Посылаем сообщение в поток. HWND Window = (HWND) Message->mp2; WinPostQueueMsg( Enhancer.Modules.Rooms->Message_queue, SM_CHECK_WINDOW, (MPARAM) Window, 0 ); } } // Добиваемся правильной работы потоков после перехода между комнатами. if( Rooms.Settings.Synchronize_arranger_and_rooms ) { // Если была нажата кнопка мыши - считаем, что смена комнат завершена. if( Message->msg == WM_BUTTON1DOWN || Message->msg == WM_BUTTON2DOWN || Message->msg == WM_BUTTON3DOWN ) if( Message->hwnd != CurtainWindow() ) if( MouseIsBusy() ) Rooms.Settings.Synchronize_arranger_and_rooms = 0; } } // Возврат. return; }
// Input_window - окно, Command - какие буквы надо вставить. VOID Clipper_PasteFireFoxCharacters( HWND Input_window, ULONG Command ) { // Запоминаем содержимое Clipboard. Для работы с FireFox требуется не только // обыкновеннай текст, но и текст в кодировке UCS2, которую понимает Mozilla. if( Clipper.RTSettings.Clipboard_data_Text != NULL ) { DosFreeMem( Clipper.RTSettings.Clipboard_data_Text ); Clipper.RTSettings.Clipboard_data_Text = NULL; } if( Clipper.RTSettings.Clipboard_data_UCS2 != NULL ) { DosFreeMem( Clipper.RTSettings.Clipboard_data_UCS2 ); Clipper.RTSettings.Clipboard_data_UCS2 = NULL; } { Clipper.RTSettings.Clipboard_data_Text_length = 0; Clipper.RTSettings.Clipboard_data_UCS2_length = 0; INT Max_length = 16384; PBYTE Text = NULL; if( DosAllocMem( (PPVOID) &Text, Max_length, PAG_ALLOCATE ) != NO_ERROR ) return; GetStringFromClipboard( Enhancer.Application, Text, Max_length ); INT Real_length = strlen( Text ) + 1; DosFreeMem( Text ); Text = NULL; Clipper.RTSettings.Clipboard_data_Text_length = Real_length; Clipper.RTSettings.Clipboard_data_UCS2_length = Real_length * 2; } if( DosAllocMem( (PPVOID) &Clipper.RTSettings.Clipboard_data_Text, Clipper.RTSettings.Clipboard_data_Text_length, PAG_ALLOCATE ) != NO_ERROR ) return; if( DosAllocMem( (PPVOID) &Clipper.RTSettings.Clipboard_data_UCS2, Clipper.RTSettings.Clipboard_data_UCS2_length, PAG_ALLOCATE ) != NO_ERROR ) return; bzero( Clipper.RTSettings.Clipboard_data_Text, Clipper.RTSettings.Clipboard_data_Text_length ); bzero( Clipper.RTSettings.Clipboard_data_UCS2, Clipper.RTSettings.Clipboard_data_UCS2_length ); CHAR Mozilla_internal_format[] = "text/unicode"; GetStringFromClipboard( Enhancer.Application, Clipper.RTSettings.Clipboard_data_Text, Clipper.RTSettings.Clipboard_data_Text_length, Clipper.RTSettings.Clipboard_data_UCS2, Clipper.RTSettings.Clipboard_data_UCS2_length, Mozilla_internal_format ); // Задаем новую строку в обычном виде и в виде UCS2-строки. BYTE Common_string[ 3 ] = { 0x00, 0x00, 0x00 }; BYTE UCS2LittleEndian_string[ 6 ] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; LONG UCS2LittleEndian_string_length = 0; #include "Modules\\Clipper\\Clipper_ffx.cpp" if( Command == SM_FFX_PASTE_DASH ) { Common_string[ 0 ] = '-'; Common_string[ 1 ] = 0x00; UCS2LittleEndian_string[ 0 ] = Dash_in_Unicode[ 1 ]; UCS2LittleEndian_string[ 1 ] = Dash_in_Unicode[ 0 ]; UCS2LittleEndian_string[ 2 ] = 0x00; UCS2LittleEndian_string[ 3 ] = 0x00; UCS2LittleEndian_string_length = 4; } if( Command == SM_FFX_PASTE_QUOTES_1 ) { Common_string[ 0 ] = '"'; Common_string[ 1 ] = '"'; Common_string[ 2 ] = 0x00; UCS2LittleEndian_string[ 0 ] = Primary_quote_1_in_Unicode[ 1 ]; UCS2LittleEndian_string[ 1 ] = Primary_quote_1_in_Unicode[ 0 ]; UCS2LittleEndian_string[ 2 ] = Primary_quote_2_in_Unicode[ 1 ]; UCS2LittleEndian_string[ 3 ] = Primary_quote_2_in_Unicode[ 0 ]; UCS2LittleEndian_string[ 4 ] = 0x00; UCS2LittleEndian_string[ 5 ] = 0x00; UCS2LittleEndian_string_length = 6; } if( Command == SM_FFX_PASTE_QUOTES_2 ) { Common_string[ 0 ] = '"'; Common_string[ 1 ] = '"'; Common_string[ 2 ] = 0x00; UCS2LittleEndian_string[ 0 ] = Secondary_quote_1_in_Unicode[ 1 ]; UCS2LittleEndian_string[ 1 ] = Secondary_quote_1_in_Unicode[ 0 ]; UCS2LittleEndian_string[ 2 ] = Secondary_quote_2_in_Unicode[ 1 ]; UCS2LittleEndian_string[ 3 ] = Secondary_quote_2_in_Unicode[ 0 ]; UCS2LittleEndian_string[ 4 ] = 0x00; UCS2LittleEndian_string[ 5 ] = 0x00; UCS2LittleEndian_string_length = 6; } PutStringIntoClipboard( Enhancer.Application, Common_string, UCS2LittleEndian_string, UCS2LittleEndian_string_length, Mozilla_internal_format ); // Посылаем в очередь окна сообщение WM_MARK. При его получении можно // будет изменить состояние клавиатуры и направить в окно сообщение WM_CHAR. HMQ Message_queue = WinQueryWindowULong( Input_window, QWL_HMQ ); WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_POST_CTRL_V, (MPARAM) Input_window ); // Возврат. return; }