void OnMenuAbout() { if (gHwndAbout) { SetActiveWindow(gHwndAbout); return; } if (!gAtomAbout) { WNDCLASSEX wcex; FillWndClassEx(wcex, ghinst, ABOUT_CLASS_NAME, WndProcAbout); wcex.hIcon = LoadIcon(ghinst, MAKEINTRESOURCE(IDI_SUMATRAPDF)); gAtomAbout = RegisterClassEx(&wcex); CrashIf(!gAtomAbout); } gHwndAbout = CreateWindow( ABOUT_CLASS_NAME, ABOUT_WIN_TITLE, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, ghinst, NULL); if (!gHwndAbout) return; ToggleWindowStyle(gHwndAbout, WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT, IsUIRightToLeft(), GWL_EXSTYLE); // get the dimensions required for the about box's content RectI rc; PAINTSTRUCT ps; HDC hdc = BeginPaint(gHwndAbout, &ps); SetLayout(hdc, LAYOUT_LTR); UpdateAboutLayoutInfo(gHwndAbout, hdc, &rc); EndPaint(gHwndAbout, &ps); rc.Inflate(ABOUT_RECT_PADDING, ABOUT_RECT_PADDING); // resize the new window to just match these dimensions WindowRect wRc(gHwndAbout); ClientRect cRc(gHwndAbout); wRc.dx += rc.dx - cRc.dx; wRc.dy += rc.dy - cRc.dy; MoveWindow(gHwndAbout, wRc.x, wRc.y, wRc.dx, wRc.dy, FALSE); ShowWindow(gHwndAbout, SW_SHOW); }
void NotificationWnd::UpdateWindowPosition(const WCHAR *message, bool init) { // compute the length of the message RECT rc = ClientRect(self).ToRECT(); HDC hdc = GetDC(self); HFONT oldfnt = SelectFont(hdc, font); DrawText(hdc, message, -1, &rc, DT_CALCRECT | DT_SINGLELINE | DT_NOPREFIX); SelectFont(hdc, oldfnt); ReleaseDC(self, hdc); RectI rectMsg = RectI::FromRECT(rc); if (hasCancel) { rectMsg.dy = std::max(rectMsg.dy, 16); rectMsg.dx += 20; } rectMsg.Inflate(PADDING, PADDING); if (shrinkLimit < 1.0f) { ClientRect rcOrig(self); if (rectMsg.dx < rcOrig.dx && rectMsg.dx > rcOrig.dx * shrinkLimit) rectMsg.dx = rcOrig.dx; } // adjust the window to fit the message (only shrink the window when there's no progress bar) if (!hasProgress) { SetWindowPos(self, nullptr, 0, 0, rectMsg.dx, rectMsg.dy, SWP_NOMOVE | SWP_NOZORDER); } else if (init) { RectI rect = WindowRect(self); rect.dx = std::max(progressWidth + 2 * PADDING, rectMsg.dx); rect.dy = rectMsg.dy + PROGRESS_HEIGHT + PADDING / 2; SetWindowPos(self, nullptr, 0, 0, rect.dx, rect.dy, SWP_NOMOVE | SWP_NOZORDER); } else if (rectMsg.dx > progressWidth + 2 * PADDING) { SetWindowPos(self, nullptr, 0, 0, rectMsg.dx, WindowRect(self).dy, SWP_NOMOVE | SWP_NOZORDER); } // move the window to the right for a right-to-left layout if (IsUIRightToLeft()) { HWND parent = GetParent(self); RectI rect = MapRectToWindow(WindowRect(self), HWND_DESKTOP, parent); rect.x = WindowRect(parent).dx - rect.dx - TL_MARGIN - GetSystemMetrics(SM_CXVSCROLL); SetWindowPos(self, nullptr, rect.x, rect.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } }
void PaintTransparentRectangles(HDC hdc, RectI screenRc, Vec<RectI>& rects, COLORREF selectionColor, BYTE alpha, int margin) { using namespace Gdiplus; // create path from rectangles GraphicsPath path(FillModeWinding); screenRc.Inflate(margin, margin); for (size_t i = 0; i < rects.Count(); i++) { RectI rc = rects.At(i).Intersect(screenRc); if (!rc.IsEmpty()) path.AddRectangle(Rect(rc.x, rc.y, rc.dx, rc.dy)); } // fill path (and draw optional outline margin) Graphics gs(hdc); Color c(alpha, GetRValue(selectionColor), GetGValue(selectionColor), GetBValue(selectionColor)); gs.FillPath(&SolidBrush(c), &path); if (margin) { path.Outline(NULL, 0.2f); gs.DrawPath(&Pen(Color(alpha, 0, 0, 0), (REAL)margin), &path); } }
LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) { NPP instance = (NPP)GetWindowLongPtr(hWnd, GWLP_USERDATA); if (uiMsg == WM_PAINT) { InstanceData *data = (InstanceData *)instance->pdata; PAINTSTRUCT ps; HDC hDC = BeginPaint(hWnd, &ps); HBRUSH brushBg = CreateSolidBrush(COL_WINDOW_BG); HFONT hFont = GetSimpleFont(hDC, L"MS Shell Dlg", 14); bool isRtL = IsLanguageRtL(gTranslationIdx); // set up double buffering RectI rcClient = ClientRect(hWnd); DoubleBuffer buffer(hWnd, rcClient); HDC hDCBuffer = buffer.GetDC(); // display message centered in the window RECT rectClient = rcClient.ToRECT(); FillRect(hDCBuffer, &rectClient, brushBg); hFont = (HFONT)SelectObject(hDCBuffer, hFont); SetTextColor(hDCBuffer, RGB(0, 0, 0)); SetBkMode(hDCBuffer, TRANSPARENT); DrawCenteredText(hDCBuffer, rcClient, data->message, isRtL); // draw a progress bar, if a download is in progress if (0 < data->progress && data->progress <= 1) { SIZE msgSize; RectI rcProgress = rcClient; HBRUSH brushProgress = CreateSolidBrush(RGB(0x80, 0x80, 0xff)); GetTextExtentPoint32(hDCBuffer, data->message, (int)str::Len(data->message), &msgSize); rcProgress.Inflate(-(rcProgress.dx - msgSize.cx) / 2, -(rcProgress.dy - msgSize.cy) / 2 + 2); rcProgress.Offset(0, msgSize.cy + 4 + 2); RECT rectProgress = rcProgress.ToRECT(); FillRect(hDCBuffer, &rectProgress, GetStockBrush(WHITE_BRUSH)); RectI rcProgressAll = rcProgress; rcProgress.dx = (int)(data->progress * rcProgress.dx); rectProgress = rcProgress.ToRECT(); FillRect(hDCBuffer, &rectProgress, brushProgress); DeleteObject(brushProgress); ScopedMem<WCHAR> currSize(FormatSizeSuccint(data->currSize)); if (0 == data->totalSize || data->currSize > data->totalSize) { // total size unknown or bogus => show just the current size DrawCenteredText(hDCBuffer, rcProgressAll, currSize, isRtL); } else { ScopedMem<WCHAR> totalSize(FormatSizeSuccint(data->totalSize)); ScopedMem<WCHAR> s(str::Format(_TR("%s of %s"), currSize, totalSize)); DrawCenteredText(hDCBuffer, rcProgressAll, s, isRtL); } } // draw the buffer on screen buffer.Flush(hDC); DeleteObject(SelectObject(hDCBuffer, hFont)); DeleteObject(brushBg); EndPaint(hWnd, &ps); HWND hChild = FindWindowEx(hWnd, NULL, NULL, NULL); if (hChild) InvalidateRect(hChild, NULL, FALSE); } else if (uiMsg == WM_SIZE) { HWND hChild = FindWindowEx(hWnd, NULL, NULL, NULL); if (hChild) { ClientRect rcClient(hWnd); MoveWindow(hChild, rcClient.x, rcClient.y, rcClient.dx, rcClient.dy, FALSE); } } else if (uiMsg == WM_COPYDATA) { COPYDATASTRUCT *cds = (COPYDATASTRUCT *)lParam; if (cds && 0x4C5255 /* URL */ == cds->dwData) { plogf("sp: NPN_GetURL %s", cds->dwData, (const char *)cds->lpData); gNPNFuncs.geturl(instance, (const char *)cds->lpData, "_blank"); return TRUE; } } return DefWindowProc(hWnd, uiMsg, wParam, lParam); }
static void DrawCaptionButton(DRAWITEMSTRUCT *item, WindowInfo *win) { if (!item || item->CtlType != ODT_BUTTON) return; RectI rc = RectI::FromRECT(item->rcItem); DoubleBuffer buffer(item->hwndItem, rc); HDC memDC = buffer.GetDC(); UINT button = item->CtlID - BTN_ID_FIRST; int partId = 0, stateId; UINT state = (UINT)-1; switch (button) { case CB_MINIMIZE: partId = WP_MINBUTTON; state = DFCS_CAPTIONMIN; break; case CB_MAXIMIZE: partId = WP_MAXBUTTON; state = DFCS_CAPTIONMAX; break; case CB_RESTORE: partId = WP_RESTOREBUTTON; state = DFCS_CAPTIONRESTORE; break; case CB_CLOSE: partId = WP_CLOSEBUTTON; state = DFCS_CAPTIONCLOSE; break; } if (ODS_SELECTED & item->itemState) { stateId = CBS_PUSHED; state |= DFCS_PUSHED; } else if (ODS_HOTLIGHT & item->itemState) { stateId = CBS_HOT; state |= DFCS_HOT; } else if (ODS_DISABLED & item->itemState) { stateId = CBS_DISABLED; state |= DFCS_INACTIVE; } else if (ODS_INACTIVE & item->itemState) stateId = CBS_INACTIVE; else stateId = CBS_NORMAL; // draw system button if (win->caption->theme) { if (partId) { if (vss::IsThemeBackgroundPartiallyTransparent(win->caption->theme, partId, stateId)) PaintCaptionBackground(memDC, win, false); vss::DrawThemeBackground(win->caption->theme, memDC, partId, stateId, &item->rcItem, NULL); } } else if (state != (UINT)-1) DrawFrameControl(memDC, &item->rcItem, DFC_CAPTION, state); // draw menu's button if (button == CB_MENU) { PaintCaptionBackground(memDC, win, false); Graphics graphics(memDC); if (CBS_PUSHED != stateId && ODS_FOCUS & item->itemState) stateId = CBS_HOT; BYTE buttonRGB = CBS_PUSHED == stateId ? 0 : CBS_HOT == stateId ? 255 : 1; if (buttonRGB != 1) { // paint the background if (GetLightness(win->caption->textColor) > GetLightness(win->caption->bgColor)) buttonRGB ^= 0xff; BYTE buttonAlpha = BYTE((255 - abs((int)GetLightness(win->caption->bgColor) - buttonRGB)) / 2); SolidBrush br(Color(buttonAlpha, buttonRGB, buttonRGB, buttonRGB)); graphics.FillRectangle(&br, rc.x, rc.y, rc.dx, rc.dy); } // draw the three lines COLORREF c = win->caption->textColor; Pen p(Color(GetRValueSafe(c), GetGValueSafe(c), GetBValueSafe(c)), floor((float)rc.dy / 8.0f)); rc.Inflate(-int(rc.dx * 0.2f + 0.5f), -int(rc.dy * 0.3f + 0.5f)); for (int i = 0; i < 3; i++) { graphics.DrawLine(&p, rc.x, rc.y + i * rc.dy / 2, rc.x + rc.dx, rc.y + i * rc.dy / 2); } } buffer.Flush(item->hDC); }
LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) { InstanceData *data = (InstanceData *)GetWindowLongPtr(hWnd, GWLP_USERDATA); if (uiMsg == WM_PAINT) { PAINTSTRUCT ps; HDC hDC = BeginPaint(hWnd, &ps); HBRUSH brushBg = CreateSolidBrush(COL_WINDOW_BG); HFONT hFont = GetSimpleFont(hDC, _T("MS Shell Dlg"), 14); // set up double buffering RectI rcClient = ClientRect(hWnd); DoubleBuffer buffer(hWnd, rcClient); HDC hDCBuffer = buffer.GetDC(); // display message centered in the window FillRect(hDCBuffer, &rcClient.ToRECT(), brushBg); hFont = (HFONT)SelectObject(hDCBuffer, hFont); SetTextColor(hDCBuffer, RGB(0, 0, 0)); SetBkMode(hDCBuffer, TRANSPARENT); DrawCenteredText(hDCBuffer, rcClient, data->message); // draw a progress bar, if a download is in progress if (0 < data->progress && data->progress <= 1) { SIZE msgSize; RectI rcProgress = rcClient; HBRUSH brushProgress = CreateSolidBrush(RGB(0x80, 0x80, 0xff)); GetTextExtentPoint32(hDCBuffer, data->message, (int)str::Len(data->message), &msgSize); rcProgress.Inflate(-(rcProgress.dx - msgSize.cx) / 2, -(rcProgress.dy - msgSize.cy) / 2 + 2); rcProgress.Offset(0, msgSize.cy + 4 + 2); FillRect(hDCBuffer, &rcProgress.ToRECT(), GetStockBrush(WHITE_BRUSH)); RectI rcProgressAll = rcProgress; rcProgress.dx = (int)(data->progress * rcProgress.dx); FillRect(hDCBuffer, &rcProgress.ToRECT(), brushProgress); DeleteObject(brushProgress); ScopedMem<TCHAR> currSize(FormatSizeSuccint(data->currSize)); if (0 == data->totalSize || data->currSize > data->totalSize) { // total size unknown or bogus => show just the current size DrawCenteredText(hDCBuffer, rcProgressAll, currSize); } else { ScopedMem<TCHAR> totalSize(FormatSizeSuccint(data->totalSize)); ScopedMem<TCHAR> s(str::Format(_T("%s of %s"), currSize, totalSize)); DrawCenteredText(hDCBuffer, rcProgressAll, s); } } // draw the buffer on screen buffer.Flush(hDC); DeleteObject(SelectObject(hDCBuffer, hFont)); DeleteObject(brushBg); EndPaint(hWnd, &ps); HWND hChild = FindWindowEx(hWnd, NULL, NULL, NULL); if (hChild) InvalidateRect(hChild, NULL, FALSE); } else if (uiMsg == WM_SIZE) { HWND hChild = FindWindowEx(hWnd, NULL, NULL, NULL); if (hChild) { ClientRect rcClient(hWnd); MoveWindow(hChild, rcClient.x, rcClient.y, rcClient.dx, rcClient.dy, FALSE); } } return DefWindowProc(hWnd, uiMsg, wParam, lParam); }