bool DebugScreen( void ) { if( !WndMain ) return( FALSE ); if( FocusWnd && WinIsWindow( GUIGetHAB(), FocusWnd ) && FocusWnd != WinQueryFocus( HWND_DESKTOP, 0 ) ) { WinSetFocus( HWND_DESKTOP, FocusWnd ); } if( ActiveWnd && WinIsWindow( GUIGetHAB(), ActiveWnd ) && ActiveWnd != WinQueryActiveWindow( HWND_DESKTOP, 0 ) ) { WinSetActiveWindow( HWND_DESKTOP, ActiveWnd ); } return( FALSE ); }
BOOL launchPad::lpSetLaunchPadPos(HWND hwndInsertBehind, LONG x, LONG y, LONG cx, LONG cy, ULONG fl) { if(WinIsWindow(WinQueryAnchorBlock(hwndLaunchPad), hwndPrevious)) { SWP swp; WinQueryWindowPos(hwndPrevious,&swp); return WinSetWindowPos(hwndLaunchPad, hwndInsertBehind, swp.x+swp.cx+x, y, cx, cy, fl); } else return WinSetWindowPos(hwndLaunchPad, hwndInsertBehind, x, y, cx, cy, fl); }
/*-------------------------------------------------- * Destroys the window *--------------------------------------------------*/ PMWindow& PMWindow::destroy() { // Prevent recursive destroying win_wrapper = TRUE; if( WinIsWindow( PMGUI::hab(), handle())) if( !WinDestroyWindow( handle())) PM_THROW_GUIERROR(); return *this; }
/*-------------------------------------------------- * Stop handling events *-------------------------------------------------*/ PMWindow& PMWindow::stop_handling_events() { if( WinIsWindow( PMGUI::hab(), handle())) { if( !WinSetWindowPtr( handle(), 0, 0 )) PM_THROW_GUIERROR(); if( WinSubclassWindow( handle(), win_default_handler ) == 0 ) PM_THROW_GUIERROR(); } return *this; }
BOOL CPlugin::initEmbed(ULONG dwInitData) { restorePreferences(); HWND hWndParent = (HWND)dwInitData; if(WinIsWindow((HAB)0, hWndParent)) m_hWndParent = hWndParent; WinLoadDlg(m_hWndParent, m_hWndParent, (PFNWP)TesterDlgProc, m_hInst, IDD_DIALOG_TESTER, (PVOID)this); m_bPluginReady = (m_hWnd != NULL); return m_bPluginReady; }
// Window - окно, которое надо проверить. BYTE WindowTypes_WindowIsPresent( HWND Window ) { // Проверяем, есть ли вообще такое окно. if( Window == NULLHANDLE ) return 0; if( !WinIsWindow( WinQueryAnchorBlock( Window ), Window ) ) return 0; // Проверяем, видимо ли оно. if( !WinIsWindowVisible( Window ) ) return 0; // Узнаем размер окна. RECT Rectangle = {0}; WinQueryWindowRect( Window, &Rectangle ); // Проверяем его. if( Rectangle.yTop <= 1 || Rectangle.xRight <= 1 ) return 0; // Возврат. return 1; }
// Frame_window - текстовое окно. VOID Clipper_EndVIOMarkingAndCopyText( HWND Frame_window ) { // Узнаем окно картинки. HWND SysMenu_window = WinWindowFromID( Frame_window, FID_SYSMENU ); // Если окна нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( SysMenu_window ), SysMenu_window ) ) return; // Если в меню есть строки для включения выделения: if( MenuItemIsPresent( SysMenu_window, SM_VIO_MARK ) && MenuItemIsPresent( SysMenu_window, SM_VIO_MOUSE ) ) { // Если обе строки меню для включения выделения выбраны: if( MenuItemIsChecked( SysMenu_window, SM_VIO_MARK ) && MenuItemIsChecked( SysMenu_window, SM_VIO_MOUSE ) ) { // Запоминаем выделенный текст. При этом строка для включения выделения должна перестать быть включенной. if( MenuItemIsPresent( SysMenu_window, SM_VIO_COPY ) ) WinSendMsg( Frame_window, WM_SYSCOMMAND, (MPARAM) SM_VIO_COPY, MPFROM2SHORT( CMDSRC_MENU, 0 ) ); // Выключаем выделение с помощью мыши. WinSendMsg( Frame_window, WM_SYSCOMMAND, (MPARAM) SM_VIO_MOUSE, MPFROM2SHORT( CMDSRC_MENU, 0 ) ); WinSendMsg( SysMenu_window, MM_SETITEMATTR, MPFROM2SHORT( SM_VIO_MOUSE, INCLUDE_SUBMENUS ), MPFROM2SHORT( MIA_CHECKED, 0 ) ); // Если строка меню для включения выделения все еще выбрана: if( MenuItemIsChecked( SysMenu_window, SM_VIO_MARK ) ) { // Выключаем выделение с помощью клавиатуры. WinSendMsg( Frame_window, WM_SYSCOMMAND, (MPARAM) SM_VIO_MARK, MPFROM2SHORT( CMDSRC_MENU, 0 ) ); WinSendMsg( SysMenu_window, MM_SETITEMATTR, MPFROM2SHORT( SM_VIO_MARK, INCLUDE_SUBMENUS ), MPFROM2SHORT( MIA_CHECKED, 0 ) ); } } } // Возврат. return; }
/*------------------------------------------------------------------------- ActMsgContextMenu --------------------------------------------------------------------------*/ MRESULT ActMsgContextMenu( WNDATTR *wndattr, USHORT x, USHORT y ) { BOOL state; if (Popup == NULLHANDLE) return MRFROMSHORT( TRUE ); if (MateScrollWnd != NULLHANDLE) { if (WinIsWindow( wndattr->hab, MateScrollWnd ) == FALSE) MateScrollWnd = NULLHANDLE; } state = (LPListMarkedLines( wndattr->list ) == 0); SetAttr( CMD_COPY, MIA_DISABLED, state ); SetAttr( CMD_UNMARK, MIA_DISABLED, state ); SetAttr( CMD_REARRANGE, MIA_DISABLED, state ); WinOpenClipbrd( wndattr->hab ); state = (WinQueryClipbrdData( wndattr->hab, CF_TEXT ) == 0); WinCloseClipbrd( wndattr->hab ); SetAttr( CMD_PASTE, MIA_DISABLED, state ); state = (WinQueryClipbrdViewer( wndattr->hab ) == wndattr->Client); SetAttr( CMD_ACCUM, MIA_CHECKED, state ); state = (MateScrollWnd != NULLHANDLE); SetAttr( CMD_MATE, MIA_CHECKED, state ); WinPopupMenu( wndattr->Frame, wndattr->Frame, Popup, x, y, CMD_ABOUT, PU_HCONSTRAIN | PU_VCONSTRAIN | PU_POSITIONONITEM | PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_MOUSEBUTTON2 ); return MRFROMSHORT( FALSE ); }
/****************************************************************\ * Main routine *-------------------------------------------------------------- * * Name: main() * * Purpose: Initializes the PM environment, calls the * initialization routine, creates the main * window, and polls the message queue * * Usage: * * Method: * - obtains anchor block handle and creates message * queue * - calls the initialization routine * - creates the main frame window which creates the * main client window * - polls the message queue via Get/Dispatch Msg loop * - upon exiting the loop, exits * * Returns: * 0 - if successful execution completed * 1 - if error \****************************************************************/ INT main(int argc, char *argv[]) { QMSG qmsg; /* message structure */ static int iTimeOut = THRD_EXIT_TIMEOUT; hab = WinInitialize(0UL); if(!hab) { DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR); return RETURN_ERROR; } hmq = WinCreateMsgQueue(hab, 0L); if(!hmq) { DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR); WinTerminate(hab); return RETURN_ERROR; } if(!Init(argc, argv)) { if(hwndMainFrame == NULLHANDLE) { MessageBox(HWND_DESKTOP, IDMSG_MAINWINCREATEFAILED, MB_OK | MB_ERROR, TRUE); } else { MessageBox(HWND_DESKTOP, IDMSG_INITFAILED, MB_OK | MB_ERROR, TRUE); } DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR); if (WinIsWindow(hab, hwndMainFrame)) { WinDestroyWindow(hwndMainFrame); } WinDestroyMsgQueue(hmq); WinTerminate(hab); return RETURN_ERROR; } /* Get-Dispatch Message loop */ while(WinGetMsg(hab, &qmsg, NULLHANDLE, 0UL, 0UL)) WinDispatchMsg(hab, &qmsg); /* destroy the help instance */ DestroyHelpInstance(); if (WinIsWindow(hab, hwndMainFrame)) WinDestroyWindow(hwndMainFrame); WinDestroyMsgQueue(hmq); /* give other thread a chance to exit */ while (!fThrdsDead && iTimeOut--) { DosSleep(0UL); } WinTerminate(hab); return RETURN_SUCCESS; } /* main() */
// Message определяет пришедшее сообщение. VOID Changer_ChangerMessageProcessing( PQMSG Message ) { // Устанавливаем приоритет потока. if( Message->msg == SM_PRIORITY ) { // Устанавливаем приоритет. LONG Class = (LONG) Message->mp1; LONG Delta = (LONG) Message->mp2; DosSetPriority( PRTYS_THREAD, Class, Delta, 0 ); // Запоминаем приоритет. Enhancer.Modules.Changer->Priority = MAKELONG( Class, Delta ); } // Меняем значок окна. if( Message->msg == SM_CHANGE_ICON ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Узнаем значок, который должен быть установлен. HPOINTER New_icon = (HPOINTER) Message->mp2; // Если окна рамки нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Меняем значок. Changer_ChangeWindowIcon( Frame_window, New_icon ); } // Сбрасываем значок, который был загружен с диска. if( Message->msg == SM_FREE_FILE_ICON ) { // Узнаем значок. HPOINTER Icon = (HPOINTER) Message->mp1; // Освобождаем память. WinFreeFileIcon( Icon ); } // Делаем окно доступным или недоступным для переключения. if( Message->msg == SM_SET_JUMPABLE ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Если окна рамки нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Узнаем свойство. ULONG Jumpable = (ULONG) Message->mp2; // Меняем его. if( Frame_window != GetDetectedShellWindow() ) SetJumpableFlag( Frame_window, Jumpable ); } // Меняем шрифт для текстовых окон - первый и второй шаги. if( Message->msg == SM_CHANGE_VIO_FONT || Message->msg == SM_APPLY_VIO_FONT ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Если шрифт менять не надо - возврат. if( !VIOFontMustBeChanged( Frame_window ) ) return; // Если окна рамки нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Шаг первый: вызываем окно смены шрифта и ждем его появления. if( Message->msg == SM_CHANGE_VIO_FONT ) { // Проверяем состояние окна. BYTE VIO_font_dialog = 0; FindProperty( Frame_window, PRP_VIO_FONT_DIALOG, &VIO_font_dialog ); // Если для этого окна уже был вызван диалог выбора шрифта - возврат. if( VIO_font_dialog ) return; // Вызываем окно смены шрифта. OpenVIOFontMetricsDialog( Frame_window ); // Запоминаем, что окно было показано. VIO_font_dialog = 1; SetProperty( Frame_window, PRP_VIO_FONT_DIALOG, &VIO_font_dialog ); } // Шаг второй: выбираем в нем шрифт и применяем его. if( Message->msg == SM_APPLY_VIO_FONT ) { // Выбираем шрифт. SubmitVIOFontMetricsDialog( Frame_window ); } } // Делаем окно видимым. if( Message->msg == SM_SHOW_AND_ARRANGE ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Если окна рамки нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Делаем окно видимым. if( !WinIsWindowVisible( Frame_window ) ) WinShowWindow( Frame_window, 1 ); // Если надо выравнивать текстовые окна: if( ArrangeVIOWindows() ) { // Посылаем в окно сообщение WM_MARK. Когда оно будет получено, окно можно будет выравнивать. WinPostMsg( Frame_window, WM_MARK, (MPARAM) MRK_ARRANGE_WINDOW, (MPARAM) SM_ARRANGE_VIO ); } } // Возврат. return; }
// Message определяет пришедшее сообщение. VOID Clipper_ClipperMessageProcessing( PQMSG Message ) { // Устанавливаем приоритет потока. if( Message->msg == SM_PRIORITY ) { // Устанавливаем приоритет. LONG Class = (LONG) Message->mp1; LONG Delta = (LONG) Message->mp2; DosSetPriority( PRTYS_THREAD, Class, Delta, 0 ); // Запоминаем приоритет. Enhancer.Modules.Clipper->Priority = MAKELONG( Class, Delta ); } // Включаем выделение в текстовом окне. if( Message->msg == SM_BEGIN_VIO_MARKING || Message->msg == SM_END_VIO_MARKING ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Если окна нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Включаем и выключаем выделение. if( Message->msg == SM_BEGIN_VIO_MARKING ) Clipper_BeginVIOMarking( Frame_window ); if( Message->msg == SM_END_VIO_MARKING ) Clipper_EndVIOMarkingAndCopyText( Frame_window ); } // Запоминаем выделенный текст. if( Message->msg == SM_COPY_VIO_TEXT ) { // Если в текстовых окнах не надо запоминать текст - возврат. if( !Clipper.Settings.Mouse_in_VIO ) return; // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Если окна нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Если выделение текста еще не начато - начинаем его. if( !Clipper_VIOMarkingIsInProcess( Frame_window ) ) Clipper_BeginVIOMarking( Frame_window ); // Иначе - завершаем выделение и запоминаем текст. else Clipper_EndVIOMarkingAndCopyText( Frame_window ); } // Вставляем текст в окно. if( Message->msg == SM_PASTE_VIO_TEXT ) { // Если в текстовых окнах не надо запоминать текст - возврат. if( !Clipper.Settings.Mouse_in_VIO ) return; // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Если окна нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Если в окне не идет выделение текста - вставляем текст. if( !Clipper_VIOMarkingIsInProcess( Frame_window ) ) Clipper_PasteTextToVIOWindow( Frame_window ); } // Запоминаем текст при нажатии средней кнопки мыши. if( Message->msg == SM_MB_CLICK ) { // Узнаем окно, с которым работает пользователь. HWND Input_window = (HWND) Message->mp1; // Если окна нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Input_window ), Input_window ) ) return; // Узнаем окно рабочего стола. HWND Desktop = QueryDesktopWindow(); // Узнаем время, достаточное для двойного нажатия на кнопку мыши. LONG DblClk_delta = WinQuerySysValue( Desktop, SV_DBLCLKTIME ); // Выполняем задержку, чтобы избежать двойного нажатия. while( 1 ) { // Если время последнего нажатия на среднюю кнопку мыши неизвестно - произошло двойное нажатие, возврат. // В это время в очереди потока уже лежит следующее сообщение - SM_MB_DOUBLECLICK. if( WMMBDownTime() == 0 ) { // Освобождаем указатель мыши. ResetPointer(); // Возврат. return; } // Узнаем текущее время. LONG Current_time = WinGetCurrentTime( Enhancer.Application ); // Если прошло достаточно много времени - все в порядке. if( Current_time > WMMBDownTime() ) if( Current_time - WMMBDownTime() > DblClk_delta ) break; // Если время прошло через ноль - возврат. if( Current_time < WMMBDownTime() ) { // Освобождаем указатель мыши. ResetPointer(); // Возврат. return; } // Через некоторое время - устанавливаем указатель мыши "прозрачная стрелка". if( Current_time - WMMBDownTime() > ( DblClk_delta / 2 ) ) if( Resources.Pointer_for_CopyPaste != NULLHANDLE ) WinSetPointer( QueryDesktopWindow(), Resources.Pointer_for_CopyPaste ); // Выполняем задержку. Retard(); } // Освобождаем указатель мыши. ResetPointer(); // Время последнего нажатия на среднюю кнопку мыши - неизвестно. DiscardWMMBDownTime(); // Узнаем ускоритель для этого окна. LONG Accelerator = (LONG) Message->mp2; // Запоминаем текст в окне. ClipboardMouseAction( Input_window, MOUSE_CLIPBOARD_COPY, Accelerator ); } // Вставляем текст в окно при нажатии средней кнопки мыши. if( Message->msg == SM_MB_DOUBLECLICK ) { // Узнаем окно, с которым работает пользователь. HWND Input_window = (HWND) Message->mp1; // Если окна нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Input_window ), Input_window ) ) return; // Если кнопка мыши снова была нажата - возврат. if( WMMBDownTime() ) return; // Узнаем ускоритель для этого окна. LONG Accelerator = (LONG) Message->mp2; // Вставляем текст в окно. ClipboardMouseAction( Input_window, MOUSE_CLIPBOARD_PASTE, Accelerator ); } // Вставляем текст в окно Mozilla при нажатии FireFox-клавиши. if( Message->msg >= SM_FFX_PASTE_FIRST && Message->msg <= SM_FFX_PASTE_LAST ) { // Узнаем окно, с которым работает пользователь. HWND Input_window = (HWND) Message->mp1; // Если окна нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Input_window ), Input_window ) ) return; // Вставляем текст в окно. Clipper_PasteFireFoxCharacters( Input_window, Message->msg ); } // Восстанавливаем содержимое Clipboard. if( Message->msg == SM_RESTORE_CLIPBOARD ) Clipper_RestoreClipboard(); // Возврат. return; }
// Message определяет пришедшее сообщение. VOID Diver_DiverMessageProcessing( PQMSG Message ) { // Устанавливаем приоритет потока. if( Message->msg == SM_PRIORITY ) { // Устанавливаем приоритет. LONG Class = (LONG) Message->mp1; LONG Delta = (LONG) Message->mp2; DosSetPriority( PRTYS_THREAD, Class, Delta, 0 ); // Запоминаем приоритет. Enhancer.Modules.Diver->Priority = MAKELONG( Class, Delta ); } // Узнаем свойства окна. if( Message->msg == SM_QUERY_PROPERTIES ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Если окна рамки нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Узнаем, какое свойство надо узнать. ULONG Target = (ULONG) Message->mp2; // Узнаем значок и ширину рамки окна. if( Target & WT_UNKNOWN || Target & WT_SYSMENU ) Diver_QueryWindowProperty( Frame_window, WT_SYSMENU ); // Если окно заголовка было перерисовано - узнаем заголовок. if( Target & WT_UNKNOWN || Target & WT_TITLEBAR ) Diver_QueryWindowProperty( Frame_window, WT_TITLEBAR ); // Если заголовок есть, но он еще не определен - узнаем его, когда перерисовывается рамка. if( Target & WT_BORDER ) { // Узнаем окно заголовка. HWND TitleBar_window = WinWindowFromID( Frame_window, FID_TITLEBAR ); // Если оно есть: if( TitleBar_window != NULLHANDLE ) { // Узнаем, есть ли в списке заголовок окна. CHAR Title[ SIZE_OF_TITLE ] = ""; FindProperty( Frame_window, PRP_TITLE, Title ); // Если его нет - узнаем его. if( Title[ 0 ] == 0 ) Diver_QueryWindowProperty( Frame_window, WT_TITLEBAR, NO_ACTION, 1 ); } } // Узнаем состояние кнопок в правом верхнем углу окна. // Проверять кнопки при Target == WT_TITLEBAR нельзя - может // возникнуть постоянное рисование, которое выглядит как "мигание" рамки. if( Target & WT_UNKNOWN || Target & WT_SYSMENU ) Diver_QueryWindowProperty( Frame_window, WT_MINMAX ); // Если состояние кнопок еще не определено - узнаем его, когда перерисовывается рамка. if( Target & WT_BORDER ) { // Узнаем, есть ли в списке состояние кнопок. BYTE Actions_are_detected = 0; FindProperty( Frame_window, PRP_ACTIONS, &Actions_are_detected ); // Если его нет - узнаем его. if( !Actions_are_detected ) Diver_QueryWindowProperty( Frame_window, WT_MINMAX ); } } // Проверяет состояние всех окон, когда одно из окон становится выбранным. if( Message->msg == SM_CHECK_CONTROLS ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Если окна рамки нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Проверяем состояние кнопок в окнах приложения, а также их значки. Diver_CheckWindowControls( Frame_window ); // Если окно не перестало быть выбранным - проверяем, нет ли в списке двух одновременно выбранных окон. // Для окон диалога эту проверку выполнять не надо - они всегда работают правильно. if( WindowIsActive( Frame_window ) ) if( !WindowIsAppDialog( Frame_window ) ) CheckActivityProperties( Frame_window ); } // Проверяем рамки окон постоянного размера. if( Message->msg == SM_CHECK_FRAME ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Узнаем окно, которое надо проверить. HWND Window = (HWND) Message->mp2; // Если одного из окон нет - возврат. HAB Application = WinQueryAnchorBlock( Frame_window ); if( !WinIsWindow( Application, Frame_window ) ) return; if( !WinIsWindow( Application, Window ) ) return; // Выполняем проверку. Diver_CheckWindowFrame( Frame_window, Window ); } // Возврат. return; }
// Message определяет пришедшее сообщение. Thread - поток. VOID Painter_PainterMessageProcessing( PQMSG Message, HAB Thread ) { // Устанавливаем приоритет потока. if( Message->msg == SM_PRIORITY ) { // Устанавливаем приоритет. LONG Class = (LONG) Message->mp1; LONG Delta = (LONG) Message->mp2; DosSetPriority( PRTYS_THREAD, Class, Delta, 0 ); // Запоминаем приоритет. Enhancer.Modules.Painter->Priority = MAKELONG( Class, Delta ); } // Перерисовываем рамки окон. if( Message->msg == SM_DRAW_FRAME ) { // Если рисование отключено - возврат. if( !Painter.Settings.Draw_frames ) return; // Кеш второго уровня: объединяем несколько заданий в одно. { // Ставим задание в список. Painter.RTSettings.Demand[ 0 ].Frame_window = (HWND) Message->mp1; Painter.RTSettings.Demand[ 0 ].Target = (ULONG) Message->mp2; // Забираем следующие задания из очереди и ставим их в список. INT Demand_total = 1; for( INT Count = 1; Count < PAINTER_DEMAND_TABLE; Count ++ ) { QMSG Next_message = {0}; WinPeekMsg( Thread, &Next_message, NULLHANDLE, SM_DRAW_FRAME, SM_DRAW_FRAME, PM_REMOVE ); if( Next_message.msg ) { Painter.RTSettings.Demand[ Count ].Frame_window = (HWND) Next_message.mp1; Painter.RTSettings.Demand[ Count ].Target = (ULONG) Next_message.mp2; Demand_total ++; } else { break; } } // Просматриваем составленный список и выполняем рисование. for( Count = 0; Count < Demand_total; Count ++ ) { // Узнаем окно рамки. HWND Frame_window = Painter.RTSettings.Demand[ Count ].Frame_window; // Если в списке нет значения - продолжаем перебор. if( Frame_window == NULLHANDLE ) continue; // Узнаем, какое окно надо перерисовать. ULONG Target = Painter.RTSettings.Demand[ Count ].Target; // Пробегаем список до конца и забираем задания для того же окна. if( Demand_total > 1 ) if( Count != Demand_total - 1 ) { for( INT Position = Count + 1; Position < Demand_total; Position ++ ) if( Painter.RTSettings.Demand[ Position ].Frame_window == Frame_window ) { Target = Target | Painter.RTSettings.Demand[ Position ].Target; Painter.RTSettings.Demand[ Position ].Frame_window = NULLHANDLE; } } // Если окна нет - продолжаем перебор. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) continue; // Перерисовываем рамку, применяя "общее задание". Painter_DrawWindowFrame( Frame_window, Target ); } } } // Перерисовываем картинку в левом верхнем углу окна. if( Message->msg == SM_DRAW_SYSMENU ) { // Если рисование отключено - возврат. if( !Painter.Settings.Draw_frames ) return; // Узнаем окно картинки. HWND SysMenu_window = (HWND) Message->mp1; // Если окна нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( SysMenu_window ), SysMenu_window ) ) return; // Узнаем, нажата ли картинка. LONG SysMenu_is_pressed = (LONG) Message->mp2; // Находим в списке значок окна. HPOINTER Icon = NULLHANDLE; HWND Frame_window = WinQueryWindow( SysMenu_window, QW_PARENT ); FindProperty( Frame_window, PRP_ICON, &Icon ); // Узнаем размер и расположение окна рамки. RECT Frame_rectangle = {0}; SWP Frame_placement = {0}; Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement ); // Если значок не найден - закрашиваем окно картинки. if( Icon == NULLHANDLE ) Painter_PreDrawControl( SysMenu_window, SYSCLR_BUTTONMIDDLE, 0, Frame_window, &Frame_rectangle, &Frame_placement ); // Иначе - рисуем картинку. else Painter_DrawSystemMenu( SysMenu_window, Frame_window, &Frame_rectangle, &Frame_placement, Icon, FT_UNKNOWN, SysMenu_is_pressed ); } // Перерисовываем кнопки. if( Message->msg == SM_DRAW_BUTTONS ) { // Если рисование отключено - возврат. if( !Painter.Settings.Draw_frames ) return; // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Если окна рамки нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Узнаем, как выглядит рамка окна. LONG Frame_type = FrameType( Frame_window ); // Узнаем окно заголовка. HWND TitleBar_window = WinWindowFromID( Frame_window, FID_TITLEBAR ); // Узнаем размер и расположение окна рамки. RECT Frame_rectangle = {0}; SWP Frame_placement = {0}; Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement ); // Рисуем кнопки. Painter_DrawButtons( Frame_window, Frame_type, &Frame_rectangle, &Frame_placement, TitleBar_window ); } // Задаем подходящее расположение для окна картинки и кнопок. if( Message->msg == SM_PREPARE_CONTROLS ) { // Узнаем окно рамки. HWND Frame_window = (HWND) Message->mp1; // Если окна рамки нет - возврат. if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return; // Узнаем размер и расположение окна. RECT Frame_rectangle = {0}; SWP Frame_placement = {0}; Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement ); // Задаем правильное расположение окна картинки, заголовка и других окон. // При этом окно рамки получит одно сообщение WM_PAINT вместо нескольких. Painter_PrepareWindowControls( Frame_window, FT_UNKNOWN, &Frame_rectangle, &Frame_placement, NULLHANDLE, NULLHANDLE, NULLHANDLE ); } // Обновляем окно. if( Message->msg == SM_UPDATE_FRAME ) UpdateWindow( (HWND) Message->mp1 ); // Обновляем все окна. if( Message->msg == SM_UPDATE_ALL_FRAMES ) { // Перерисовываем рамки всех окон. UpdateAllWindows( QueryDesktopWindow() ); } // Возврат. return; }