Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/engine/UpdateInstallDialog.cpp

Issue 11304082: Download updates automatically, ask to install from a modeless dialog (Closed)
Patch Set: Calculate sizes dynamically Created Aug. 2, 2013, 10:47 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/engine/UpdateInstallDialog.h ('k') | src/engine/Updater.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #include <sstream>
2 #include <string>
3 #include <Windows.h>
4
5 #include "../shared/Dictionary.h"
6 #include "../shared/Utils.h"
7 #include "UpdateInstallDialog.h"
8
9 namespace
10 {
11 LRESULT CALLBACK ProcessWindowMessage(HWND window, UINT message,
12 WPARAM wParam, LPARAM lParam)
13 {
14 switch (message)
15 {
16 case WM_CLOSE:
17 PostQuitMessage(1);
18 return 0;
19 case WM_COMMAND:
20 switch (LOWORD(wParam))
21 {
22 case IDYES:
23 PostQuitMessage(0);
24 return 0;
25 case IDNO:
26 PostQuitMessage(1);
27 return 0;
28 }
29 break;
30 }
31 return DefWindowProc(window, message, wParam, lParam);
32 }
33
34 HWND CreateDialogWindow()
35 {
36 const std::wstring windowClassName = L"ABP_UPDATE_INSTALL_DIALOG";
37 WNDCLASSEXW windowClass = {};
38 windowClass.cbSize = sizeof(windowClass);
39 windowClass.lpfnWndProc = ProcessWindowMessage;
40 windowClass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_MENU + 1);
41 windowClass.lpszClassName = windowClassName.c_str();
42 RegisterClassEx(&windowClass);
43
44 Dictionary* dictionary = Dictionary::GetInstance();
45 std::wstring title =
46 dictionary->Lookup("updater", "install-question-title");
47
48 return CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
49 windowClassName.c_str(), title.c_str(), WS_SYSMENU,
50 0, 0, 0, 0, 0, 0, 0, 0);
51 }
52
53 int GetAverageCharacterWidth(HDC deviceContext)
54 {
55 std::wstring alphabet;
56 for (wchar_t letter = L'A'; letter != 'Z'; letter++)
57 alphabet += letter;
58 RECT alphabetRect = {};
59 DrawTextW(deviceContext, alphabet.c_str(), -1, &alphabetRect,
60 DT_CALCRECT | DT_NOPREFIX);
61 return alphabetRect.right / alphabet.length();
62 }
63
64 HWND CreateText(HWND parent)
65 {
66 Dictionary* dictionary = Dictionary::GetInstance();
67 std::wstring text = dictionary->Lookup("updater", "install-question-text");
68
69 HDC deviceContext = GetDC(parent);
70 const int characterWidth = GetAverageCharacterWidth(deviceContext);
71 const int lineLength = 40;
72 const int textWidth = lineLength * characterWidth;
73
74 RECT textRect = {};
75 textRect.right = textWidth;
76 DrawTextW(deviceContext, text.c_str(), -1, &textRect,
77 DT_CALCRECT | DT_NOPREFIX | DT_WORDBREAK);
78 const int textHeight = textRect.bottom;
79
80 return CreateWindowW(L"STATIC", text.c_str(),
81 WS_CHILD | WS_VISIBLE| SS_LEFT, 0, 0,
82 textWidth, textHeight, parent, 0, 0, 0);
83 }
84
85 HWND CreateButtons(HWND parent)
86 {
87 const std::wstring panelClassName = L"ABP_PANEL";
88 WNDCLASSW panelClass = {};
89 panelClass.lpfnWndProc =
90 reinterpret_cast<WNDPROC>(GetWindowLongPtr(parent, GWLP_WNDPROC));
91 panelClass.lpszClassName = panelClassName.c_str();
92 RegisterClass(&panelClass);
93
94 Dictionary* dictionary = Dictionary::GetInstance();
95 const std::wstring yesLabel = dictionary->Lookup("general", "button-yes");
96 const std::wstring noLabel = dictionary->Lookup("general", "button-no");
97
98 HDC deviceContext = GetDC(parent);
99 RECT yesButtonRect = {};
100 DrawTextW(deviceContext, yesLabel.c_str(), -1, &yesButtonRect,
101 DT_CALCRECT | DT_NOPREFIX);
102 RECT noButtonRect = {};
103 DrawTextW(deviceContext, noLabel.c_str(), -1, &noButtonRect,
104 DT_CALCRECT | DT_NOPREFIX);
105
106 const int minButtonWidth = 120;
107 const int minButtonHeight = 30;
108 const int buttonPadding = 5;
109 int yesButtonWidth = yesButtonRect.right + buttonPadding * 2;
110 yesButtonWidth = max(yesButtonWidth, minButtonWidth);
111 int noButtonWidth = noButtonRect.right + buttonPadding * 2;
112 noButtonWidth = max(noButtonWidth, minButtonWidth);
113 int buttonHeight = max(yesButtonRect.bottom, noButtonRect.bottom)
114 + buttonPadding * 2;
115 buttonHeight = max(buttonHeight, minButtonHeight);
116
117 const int gap = 10;
118 const int panelWidth = yesButtonWidth + gap + noButtonWidth;
119 const int panelHeight = buttonHeight;
120
121 const DWORD flags = WS_CHILD | WS_VISIBLE;
122 HWND buttons = CreateWindowW(panelClassName.c_str(), 0, flags, 0, 0,
123 panelWidth, panelHeight, parent, 0, 0, 0);
124 CreateWindowW(L"BUTTON", yesLabel.c_str(), flags,
125 0, 0, yesButtonWidth, buttonHeight,
126 buttons, reinterpret_cast<HMENU>(IDYES), 0, 0);
127 CreateWindowW(L"BUTTON", noLabel.c_str(), flags,
128 yesButtonWidth + gap, 0, noButtonWidth, buttonHeight,
129 buttons, reinterpret_cast<HMENU>(IDNO), 0, 0);
130 return buttons;
131 }
132
133 void UpdateSizes(HWND window, const HWND text, const HWND buttons)
134 {
135 RECT textRect;
136 GetWindowRect(text, &textRect);
137
138 RECT buttonsRect;
139 GetWindowRect(buttons, &buttonsRect);
140
141 const int padding = 10;
142 const int margin = 10;
143 const int gap = 10;
144 const int contentWidth = max(textRect.right, buttonsRect.right);
145 const int contentHeight = textRect.bottom + buttonsRect.bottom + margin;
146 const int windowWidth = contentWidth + padding * 2;
147 const int windowHeight = contentHeight + padding * 2;
148
149 RECT workArea;
150 SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0);
151 const int windowX = workArea.right - windowWidth - margin;
152 const int windowY = workArea.bottom - windowHeight - margin;
153 SetWindowPos(window, 0, windowX, windowY, windowWidth, windowHeight, 0);
154
155 const int textX = padding;
156 const int textY = padding;
157 SetWindowPos(text, 0, padding, padding, 0, 0, SWP_NOSIZE);
158
159 const int buttonsX = windowWidth - buttonsRect.right - padding;
160 const int buttonsY = windowHeight - buttonsRect.bottom - padding;
161 SetWindowPos(buttons, 0, buttonsX, buttonsY, 0, 0, SWP_NOSIZE);
162 }
163 }
164
165 UpdateInstallDialog::UpdateInstallDialog()
166 {
167 window = CreateDialogWindow();
168 HWND text = CreateText(window);
169 HWND buttons = CreateButtons(window);
170 UpdateSizes(window, text, buttons);
171 }
172
173 UpdateInstallDialog::~UpdateInstallDialog()
174 {
175 DestroyWindow(window);
176 }
177
178 bool UpdateInstallDialog::Show()
179 {
180 ShowWindow(window, SW_SHOW);
181 MSG message;
182 while(GetMessage(&message, 0, 0, 0) > 0)
183 {
184 TranslateMessage(&message);
185 DispatchMessage(&message);
186 }
187 ShowWindow(window, SW_HIDE);
188 return message.wParam == 0;
189 }
OLDNEW
« no previous file with comments | « src/engine/UpdateInstallDialog.h ('k') | src/engine/Updater.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld