Release 960114
[wine.git] / windows / msgbox.c
bloba83b8cc647cd214b56e71ed15ef7bd5788b33fbe
1 /*
2 * Message boxes
4 * Copyright 1995 Bernd Schmidt
6 */
8 #include "windows.h"
9 #include "dlgs.h"
10 #include "selectors.h"
11 #include "alias.h"
12 #include "relay32.h"
13 #include "win.h"
14 #include "resource.h"
15 #include "task.h"
17 typedef struct {
18 LPSTR title;
19 LPSTR text;
20 WORD type;
21 } MSGBOX, *LPMSGBOX;
23 LRESULT SystemMessageBoxProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
25 LPMSGBOX lpmb;
26 RECT rect, textrect;
27 HWND hItem;
28 HDC hdc;
29 LONG lRet;
30 int i, buttons, bwidth, bheight, theight, wwidth, bpos;
31 int borheight, iheight, tiheight;
33 switch(message) {
34 case WM_INITDIALOG:
35 lpmb = (LPMSGBOX)lParam;
36 if (lpmb->title != NULL) {
37 SetWindowText(hwnd, lpmb->title);
39 SetWindowText(GetDlgItem(hwnd, 100), lpmb->text);
40 /* Hide not selected buttons */
41 switch(lpmb->type & MB_TYPEMASK) {
42 case MB_OK:
43 ShowWindow(GetDlgItem(hwnd, 2), SW_HIDE);
44 /* fall through */
45 case MB_OKCANCEL:
46 ShowWindow(GetDlgItem(hwnd, 3), SW_HIDE);
47 ShowWindow(GetDlgItem(hwnd, 4), SW_HIDE);
48 ShowWindow(GetDlgItem(hwnd, 5), SW_HIDE);
49 ShowWindow(GetDlgItem(hwnd, 6), SW_HIDE);
50 ShowWindow(GetDlgItem(hwnd, 7), SW_HIDE);
51 break;
52 case MB_ABORTRETRYIGNORE:
53 ShowWindow(GetDlgItem(hwnd, 1), SW_HIDE);
54 ShowWindow(GetDlgItem(hwnd, 2), SW_HIDE);
55 ShowWindow(GetDlgItem(hwnd, 6), SW_HIDE);
56 ShowWindow(GetDlgItem(hwnd, 7), SW_HIDE);
57 break;
58 case MB_YESNO:
59 ShowWindow(GetDlgItem(hwnd, 2), SW_HIDE);
60 /* fall through */
61 case MB_YESNOCANCEL:
62 ShowWindow(GetDlgItem(hwnd, 1), SW_HIDE);
63 ShowWindow(GetDlgItem(hwnd, 3), SW_HIDE);
64 ShowWindow(GetDlgItem(hwnd, 4), SW_HIDE);
65 ShowWindow(GetDlgItem(hwnd, 5), SW_HIDE);
66 break;
68 /* Set the icon */
69 switch(lpmb->type & MB_ICONMASK) {
70 case MB_ICONEXCLAMATION:
71 SendDlgItemMessage(hwnd, stc1, STM_SETICON,
72 (WPARAM)LoadIcon(0, IDI_EXCLAMATION), 0);
73 break;
74 case MB_ICONQUESTION:
75 SendDlgItemMessage(hwnd, stc1, STM_SETICON,
76 (WPARAM)LoadIcon(0, IDI_QUESTION), 0);
77 break;
78 case MB_ICONASTERISK:
79 SendDlgItemMessage(hwnd, stc1, STM_SETICON,
80 (WPARAM)LoadIcon(0, IDI_ASTERISK), 0);
81 break;
82 case MB_ICONHAND:
83 default:
84 SendDlgItemMessage(hwnd, stc1, STM_SETICON,
85 (WPARAM)LoadIcon(0, IDI_HAND), 0);
86 break;
89 /* Position everything */
90 GetWindowRect(hwnd, &rect);
91 borheight = rect.bottom - rect.top;
92 wwidth = rect.right - rect.left;
93 GetClientRect(hwnd, &rect);
94 borheight -= rect.bottom - rect.top;
96 /* Get the icon height */
97 GetWindowRect(GetDlgItem(hwnd, 1088), &rect);
98 iheight = rect.bottom - rect.top;
100 /* Get the number of visible buttons and their width */
101 GetWindowRect(GetDlgItem(hwnd, 2), &rect);
102 bheight = rect.bottom - rect.top;
103 bwidth = rect.left;
104 GetWindowRect(GetDlgItem(hwnd, 1), &rect);
105 bwidth -= rect.left;
106 for (buttons = 0, i = 1; i < 8; i++) {
107 hItem = GetDlgItem(hwnd, i);
108 if (GetWindowLong(hItem, GWL_STYLE) & WS_VISIBLE) {
109 buttons++;
113 /* Get the text size */
114 hItem = GetDlgItem(hwnd, 100);
115 GetWindowRect(hItem, &textrect);
116 MapWindowPoints(0, hwnd, (LPPOINT)&textrect, 2);
118 GetClientRect(hItem, &rect);
119 hdc = GetDC(hItem);
120 lRet = DrawText(hdc, lpmb->text, -1, &rect,
121 DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_CALCRECT);
122 theight = rect.bottom - rect.top;
123 tiheight = 16 + MAX(iheight, theight);
124 ReleaseDC(hItem, hdc);
126 /* Position the text */
127 SetWindowPos(hItem, 0, textrect.left, (tiheight - theight) / 2,
128 rect.right - rect.left, theight,
129 SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
131 /* Position the icon */
132 hItem = GetDlgItem(hwnd, 1088);
133 GetWindowRect(hItem, &rect);
134 MapWindowPoints(0, hwnd, (LPPOINT)&rect, 2);
135 SetWindowPos(hItem, 0, rect.left, (tiheight - iheight) / 2, 0, 0,
136 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
138 /* Resize the window */
139 SetWindowPos(hwnd, 0, 0, 0, wwidth, 8 + tiheight + bheight + borheight,
140 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
142 /* Position the buttons */
143 bpos = (wwidth - bwidth * buttons) / 2;
144 GetWindowRect(GetDlgItem(hwnd, 1), &rect);
145 for (buttons = i = 0; i < 7; i++) {
146 /* some arithmetic to get the right order for YesNoCancel windows */
147 hItem = GetDlgItem(hwnd, (i + 5) % 7 + 1);
148 if (GetWindowLong(hItem, GWL_STYLE) & WS_VISIBLE) {
149 if (buttons++ == ((lpmb->type & MB_DEFMASK) >> 8)) {
150 SetFocus(hItem);
151 SendMessage(hItem, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
153 SetWindowPos(hItem, 0, bpos, tiheight, 0, 0,
154 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
155 bpos += bwidth;
158 return 0;
159 break;
161 case WM_COMMAND:
162 switch (wParam) {
163 case IDOK:
164 case IDCANCEL:
165 case IDABORT:
166 case IDRETRY:
167 case IDIGNORE:
168 case IDYES:
169 case IDNO:
170 EndDialog(hwnd, wParam);
171 break;
173 break;
175 return 0;
178 /**************************************************************************
179 * MessageBox [USER.1]
182 int MessageBox(HWND hWnd, LPSTR text, LPSTR title, WORD type)
184 HANDLE handle;
185 MSGBOX mbox;
186 int ret;
187 DWORD WineProc,Win16Proc,Win32Proc;
188 static int initialized = 0;
190 mbox.title = title;
191 mbox.text = text;
192 mbox.type = type;
194 if (!initialized)
196 WineProc=(DWORD)SystemMessageBoxProc;
197 Win16Proc=(DWORD)GetWndProcEntry16("SystemMessageBoxProc");
198 Win32Proc=(DWORD)RELAY32_GetEntryPoint("WINPROCS32","SystemMessageBoxProc",0);
199 ALIAS_RegisterAlias(WineProc,Win16Proc,Win32Proc);
200 initialized=1;
203 handle = SYSRES_LoadResource( SYSRES_DIALOG_MSGBOX );
204 if (!handle) return 0;
205 ret = DialogBoxIndirectParam( WIN_GetWindowInstance(hWnd),
206 handle, hWnd,
207 GetWndProcEntry16("SystemMessageBoxProc"),
208 (LONG)&mbox );
209 SYSRES_FreeResource( handle );
210 return ret;
213 /**************************************************************************
214 * FatalAppExit [USER.137]
217 void FatalAppExit(WORD wAction, LPSTR str)
219 MessageBox(0, str, NULL, MB_SYSTEMMODAL | MB_OK);
220 TASK_KillCurrentTask(0);