OLD | NEW |
(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 } |
OLD | NEW |