// Place a (KB) button on the left of any possible (?)(OK)(X) buttons. BOOL PositionKBButton(HWND hwndKB, HWND hwnd) { if (hwndKB == NULL || hwnd == NULL) { return FALSE; } LONG style = GetWindowLong(hwnd, GWL_STYLE); LONG exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); // The (KB) button can only be placed on windows with a title bar if ((style|WS_CAPTION) != style) { SetWindowPos(hwndKB, 0, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE); return FALSE; } int i = 0; if ((style|WS_SYSMENU) == style) i++; // has a close (X) button if ((exStyle|WS_EX_CAPTIONOKBTN) == exStyle) i++; // has an OK button if ((exStyle|WS_EX_CONTEXTHELP) == exStyle) i++; // has a Help (?) button int x = 0; int y = 0; if (HAS_THICKFRAME(style, exStyle)) { // x = GetSystemMetrics(SM_CXFRAME); // y = GetSystemMetrics(SM_CYFRAME); //} else if (HAS_DLGFRAME(style, exStyle)) { } else if (HAS_DLGFRAME(style, exStyle) && (exStyle|WS_EX_NODRAG) != exStyle) { x = GetSystemMetrics(SM_CXDLGFRAME); y = GetSystemMetrics(SM_CYDLGFRAME); } else if (HAS_THINFRAME(style)) { x = GetSystemMetrics(SM_CXBORDER); y = GetSystemMetrics(SM_CYBORDER); } if ((style & WS_CHILD)) { if (exStyle & WS_EX_CLIENTEDGE) { x += GetSystemMetrics(SM_CXEDGE); y += GetSystemMetrics(SM_CYEDGE); } if (exStyle & WS_EX_STATICEDGE) { x += GetSystemMetrics(SM_CXBORDER); y += GetSystemMetrics(SM_CYBORDER); } } RECT rc; GetWindowRect(hwnd, &rc); int w = GetSystemMetrics(SM_CYCAPTION) - 2; int h = w; x = rc.right - i * (w + 4) - w - x - 2; // 4 is the space between buttons, 2 is the space between the right most button and the border y += rc.top + 1; SetWindowPos(hwndKB, HWND_TOP, x, y, w, h, SWP_NOACTIVATE | SWP_SHOWWINDOW); MoveWindow(GetDlgItem(hwndKB, IDC_KB_BUTTON), 0, 0, w, h, TRUE); return TRUE; }
/*********************************************************************** * NcGetInsideRect * * Get the 'inside' rectangle of a window, i.e. the whole window rectangle * but without the borders (if any). * The rectangle is in window coordinates (for drawing with GetWindowDC()). */ static void FASTCALL NcGetInsideRect(HWND Wnd, RECT *Rect) { DWORD Style; DWORD ExStyle; GetWindowRect(Wnd, Rect); Rect->right = Rect->right - Rect->left; Rect->left = 0; Rect->bottom = Rect->bottom - Rect->top; Rect->top = 0; Style = GetWindowLongPtrW(Wnd, GWL_STYLE); if (0 != (Style & WS_ICONIC)) { return; } /* Remove frame from rectangle */ ExStyle = GetWindowLongPtrW(Wnd, GWL_EXSTYLE); if (HAS_THICKFRAME(Style, ExStyle)) { InflateRect(Rect, - GetSystemMetrics(SM_CXFRAME), - GetSystemMetrics(SM_CYFRAME)); } else if (HAS_DLGFRAME(Style, ExStyle)) { InflateRect(Rect, - GetSystemMetrics(SM_CXDLGFRAME), - GetSystemMetrics(SM_CYDLGFRAME)); } else if (HAS_THINFRAME(Style, ExStyle)) { InflateRect(Rect, - GetSystemMetrics(SM_CXBORDER), - GetSystemMetrics(SM_CYBORDER)); } /* We have additional border information if the window * is a child (but not an MDI child) */ if (0 != (Style & WS_CHILD) && 0 == (ExStyle & WS_EX_MDICHILD)) { if (0 != (ExStyle & WS_EX_CLIENTEDGE)) { InflateRect(Rect, - GetSystemMetrics(SM_CXEDGE), - GetSystemMetrics(SM_CYEDGE)); } if (0 != (ExStyle & WS_EX_STATICEDGE)) { InflateRect(Rect, - GetSystemMetrics(SM_CXBORDER), - GetSystemMetrics(SM_CYBORDER)); } } }
DWORD FASTCALL GetNCHitEx(PWND pWnd, POINT pt) { RECT rcWindow, rcClient; DWORD Style, ExStyle; if (!pWnd) return HTNOWHERE; if (pWnd == UserGetDesktopWindow()) // pWnd->fnid == FNID_DESKTOP) { rcClient.left = rcClient.top = rcWindow.left = rcWindow.top = 0; rcWindow.right = UserGetSystemMetrics(SM_CXSCREEN); rcWindow.bottom = UserGetSystemMetrics(SM_CYSCREEN); rcClient.right = UserGetSystemMetrics(SM_CXSCREEN); rcClient.bottom = UserGetSystemMetrics(SM_CYSCREEN); } else { rcClient = pWnd->rcClient; rcWindow = pWnd->rcWindow; } if (!RECTL_bPointInRect(&rcWindow, pt.x, pt.y)) return HTNOWHERE; Style = pWnd->style; ExStyle = pWnd->ExStyle; if (Style & WS_MINIMIZE) return HTCAPTION; if (RECTL_bPointInRect( &rcClient, pt.x, pt.y )) return HTCLIENT; /* Check borders */ if (HAS_THICKFRAME( Style, ExStyle )) { RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXFRAME), -UserGetSystemMetrics(SM_CYFRAME) ); if (!RECTL_bPointInRect(&rcWindow, pt.x, pt.y )) { /* Check top sizing border */ if (pt.y < rcWindow.top) { if (pt.x < rcWindow.left+UserGetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT; if (pt.x >= rcWindow.right-UserGetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT; return HTTOP; } /* Check bottom sizing border */ if (pt.y >= rcWindow.bottom) { if (pt.x < rcWindow.left+UserGetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT; if (pt.x >= rcWindow.right-UserGetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT; return HTBOTTOM; } /* Check left sizing border */ if (pt.x < rcWindow.left) { if (pt.y < rcWindow.top+UserGetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT; if (pt.y >= rcWindow.bottom-UserGetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT; return HTLEFT; } /* Check right sizing border */ if (pt.x >= rcWindow.right) { if (pt.y < rcWindow.top+UserGetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT; if (pt.y >= rcWindow.bottom-UserGetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT; return HTRIGHT; } } } else /* No thick frame */ { if (HAS_DLGFRAME( Style, ExStyle )) RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXDLGFRAME), -UserGetSystemMetrics(SM_CYDLGFRAME)); else if (HAS_THINFRAME( Style, ExStyle )) RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXBORDER), -UserGetSystemMetrics(SM_CYBORDER)); if (!RECTL_bPointInRect( &rcWindow, pt.x, pt.y )) return HTBORDER; } /* Check caption */ if ((Style & WS_CAPTION) == WS_CAPTION) { if (ExStyle & WS_EX_TOOLWINDOW) rcWindow.top += UserGetSystemMetrics(SM_CYSMCAPTION) - 1; else rcWindow.top += UserGetSystemMetrics(SM_CYCAPTION) - 1; if (!RECTL_bPointInRect( &rcWindow, pt.x, pt.y )) { BOOL min_or_max_box = (Style & WS_SYSMENU) && (Style & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)); if (ExStyle & WS_EX_LAYOUTRTL) { /* Check system menu */ if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW) && NC_IconForWindow(pWnd)) { rcWindow.right -= UserGetSystemMetrics(SM_CYCAPTION) - 1; if (pt.x > rcWindow.right) return HTSYSMENU; } /* Check close button */ if (Style & WS_SYSMENU) { rcWindow.left += UserGetSystemMetrics(SM_CYCAPTION); if (pt.x < rcWindow.left) return HTCLOSE; } /* Check maximize box */ /* In Win95 there is automatically a Maximize button when there is a minimize one */ if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW)) { rcWindow.left += UserGetSystemMetrics(SM_CXSIZE); if (pt.x < rcWindow.left) return HTMAXBUTTON; } /* Check minimize box */ if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW)) { rcWindow.left += UserGetSystemMetrics(SM_CXSIZE); if (pt.x < rcWindow.left) return HTMINBUTTON; } } else { /* Check system menu */ if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW) && NC_IconForWindow(pWnd)) { rcWindow.left += UserGetSystemMetrics(SM_CYCAPTION) - 1; if (pt.x < rcWindow.left) return HTSYSMENU; } /* Check close button */ if (Style & WS_SYSMENU) { rcWindow.right -= UserGetSystemMetrics(SM_CYCAPTION); if (pt.x > rcWindow.right) return HTCLOSE; } /* Check maximize box */ /* In Win95 there is automatically a Maximize button when there is a minimize one */ if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW)) { rcWindow.right -= UserGetSystemMetrics(SM_CXSIZE); if (pt.x > rcWindow.right) return HTMAXBUTTON; } /* Check minimize box */ if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW)) { rcWindow.right -= UserGetSystemMetrics(SM_CXSIZE); if (pt.x > rcWindow.right) return HTMINBUTTON; } } return HTCAPTION; } } /* Check menu bar */ if (HAS_MENU( pWnd, Style ) && (pt.y < rcClient.top) && (pt.x >= rcClient.left) && (pt.x < rcClient.right)) return HTMENU; /* Check vertical scroll bar */ if (ExStyle & WS_EX_LAYOUTRTL) ExStyle ^= WS_EX_LEFTSCROLLBAR; if (Style & WS_VSCROLL) { if((ExStyle & WS_EX_LEFTSCROLLBAR) != 0) rcClient.left -= UserGetSystemMetrics(SM_CXVSCROLL); else rcClient.right += UserGetSystemMetrics(SM_CXVSCROLL); if (RECTL_bPointInRect( &rcClient, pt.x, pt.y )) return HTVSCROLL; } /* Check horizontal scroll bar */ if (Style & WS_HSCROLL) { rcClient.bottom += UserGetSystemMetrics(SM_CYHSCROLL); if (RECTL_bPointInRect( &rcClient, pt.x, pt.y )) { /* Check size box */ if ((Style & WS_VSCROLL) && ((((ExStyle & WS_EX_LEFTSCROLLBAR) != 0) && (pt.x <= rcClient.left + UserGetSystemMetrics(SM_CXVSCROLL))) || (((ExStyle & WS_EX_LEFTSCROLLBAR) == 0) && (pt.x >= rcClient.right - UserGetSystemMetrics(SM_CXVSCROLL))))) return HTSIZE; return HTHSCROLL; } } /* Has to return HTNOWHERE if nothing was found Could happen when a window has a customized non client area */ return HTNOWHERE; }