-
Notifications
You must be signed in to change notification settings - Fork 10
/
optionsdlg.cpp
97 lines (80 loc) · 3.27 KB
/
optionsdlg.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "stdafx.h"
#include "options.h"
#include "optionsdlg.h"
WNDPROC OptionsDlg::orgOptPSProc = 0;
void OptionsDlg::buildOptPropSheet(PROPSHEETHEADER& psh, PROPSHEETPAGE psp[],
int dlgIds[], DLGPROC dlgProcs[], int pageCnt, HWND parentWnd,
OptionsPropSheetData& data, Util::Res::ResStr& capStr)
{
for (int n = 0; n < pageCnt; ++n) {
psp[n].dwSize = sizeof(psp[n]);
psp[n].dwFlags = PSP_HASHELP;
psp[n].hInstance = app.resMod ? app.resMod : app.inst;
psp[n].pszTemplate = MAKEINTRESOURCE(dlgIds[n]);
psp[n].hIcon = 0;
psp[n].pszTitle = 0;
psp[n].pfnDlgProc = dlgProcs[n];
psp[n].lParam = reinterpret_cast<LPARAM>(&data);
psp[n].pfnCallback = 0;
psp[n].pcRefParent = 0;
}
psh.dwSize = sizeof(psh);
psh.dwFlags = PSH_HASHELP | PSH_PROPSHEETPAGE | PSH_USECALLBACK | PSH_USEHICON;
psh.hwndParent = parentWnd;
psh.hInstance = app.resMod ? app.resMod : app.inst;
psh.hIcon = app.smIcon;
psh.pszCaption = capStr;
psh.nPages = pageCnt;
psh.nStartPage = (app.optionPage >= 0 && app.optionPage < pageCnt)
? app.optionPage : 0;
psh.ppsp = psp;
psh.pfnCallback = optPSCallback;
}
void OptionsDlg::fixOptPSPos(HWND wnd)
{
// - find taskbar ("Shell_TrayWnd")
// - find notification area ("TrayNotifyWnd") (child of taskbar)
// - get center of notification area
// - determine quadrant of screen which includes the center point
// - position prop sheet at proper corner of workarea
RECT rc, rcWA, rcNW;
HWND trayWnd, notityWnd;
if (GetWindowRect(wnd, &rc)
&& SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWA, 0)
&& (trayWnd = FindWindow(L"Shell_TrayWnd", L""))
&& (notityWnd = FindWindowEx(trayWnd, 0, L"TrayNotifyWnd", L""))
&& GetWindowRect(notityWnd, &rcNW))
{
// '/2' simplified from the following two inequalities
bool isLeft = (rcNW.left + rcNW.right) < GetSystemMetrics(SM_CXSCREEN);
bool isTop = (rcNW.top + rcNW.bottom) < GetSystemMetrics(SM_CYSCREEN);
int x = isLeft ? rcWA.left : rcWA.right - (rc.right - rc.left);
int y = isTop ? rcWA.top : rcWA.bottom - (rc.bottom - rc.top);
OffsetRect(&rc, x-rc.left, y-rc.top);
Util::Wnd::moveWindow(wnd, rc);
}
}
LRESULT CALLBACK OptionsDlg::optPSSubclass(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if (msg == WM_SHOWWINDOW) {
fixOptPSPos(wnd);
// also set the big icon (for Alt-Tab)
SendMessage(wnd, WM_SETICON, ICON_BIG,
LPARAM(LoadIcon(app.inst, MAKEINTRESOURCE(IDI_APP))));
LRESULT ret = CallWindowProc(orgOptPSProc, wnd, msg, wparam, lparam);
SetWindowLong(wnd, GWL_WNDPROC, LONG(orgOptPSProc));
orgOptPSProc = 0;
return ret;
}
return CallWindowProc(orgOptPSProc, wnd, msg, wparam, lparam);
}
// remove WS_EX_CONTEXTHELP and subclass to fix pos
int CALLBACK OptionsDlg::optPSCallback(HWND wnd, UINT msg, LPARAM param)
{
if (msg == PSCB_INITIALIZED) {
// remove caption help button
ef::Win::WndH(wnd).modifyExStyle(WS_EX_CONTEXTHELP, 0);
orgOptPSProc = WNDPROC(SetWindowLong(wnd, GWL_WNDPROC, LONG(optPSSubclass)));
}
return 0;
}