Release 940405
[wine.git] / misc / message.c
blob57428e7faf4f91cda964c032e9cf06afef75f514
1 /*
2 * 'Wine' MessageBox function handling
4 * Copyright 1993 Martin Ayotte
5 */
7 static char Copyright[] = "Copyright Martin Ayotte, 1993";
9 #define DEBUG_MSGBOX
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <windows.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
18 #include <unistd.h>
19 #include "prototypes.h"
20 #include "heap.h"
21 #include "win.h"
23 extern HINSTANCE hSysRes;
24 extern HBITMAP hUpArrow;
26 typedef struct tagMSGBOX {
27 LPSTR Title;
28 LPSTR Str;
29 WORD wType;
30 WORD wRetVal;
31 BOOL ActiveFlg;
32 HWND hWndYes;
33 HWND hWndNo;
34 HWND hWndCancel;
35 HICON hIcon;
36 RECT rectIcon;
37 RECT rectStr;
38 } MSGBOX;
39 typedef MSGBOX FAR* LPMSGBOX;
41 LONG SystemMessageBoxProc(HWND hwnd, WORD message, WORD wParam, LONG lParam);
43 /**************************************************************************
44 * MessageBox [USER.1]
47 int MessageBox(HWND hWnd, LPSTR str, LPSTR title, WORD type)
49 HWND hDlg, hWndOld;
50 WND *wndPtr;
51 WNDCLASS wndClass;
52 MSG msg;
53 MSGBOX mb;
54 DWORD dwStyle;
55 HINSTANCE hInst;
56 wndPtr = WIN_FindWndPtr(hWnd);
57 #ifdef DEBUG_MSGBOX
58 printf( "MessageBox: '%s'\n", str );
59 #endif
60 if (wndPtr == NULL)
61 hInst = hSysRes;
62 else
63 hInst = wndPtr->hInstance;
64 wndClass.style = CS_HREDRAW | CS_VREDRAW ;
65 wndClass.lpfnWndProc = (WNDPROC)SystemMessageBoxProc;
66 wndClass.cbClsExtra = 0;
67 wndClass.cbWndExtra = 0;
68 wndClass.hInstance = hInst;
69 wndClass.hIcon = (HICON)NULL;
70 wndClass.hCursor = LoadCursor((HANDLE)NULL, IDC_ARROW);
71 wndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
72 wndClass.lpszMenuName = NULL;
73 wndClass.lpszClassName = "MESSAGEBOX";
74 if (!RegisterClass(&wndClass)) return 0;
75 memset(&mb, 0, sizeof(MSGBOX));
76 mb.Title = title;
77 mb.Str = str;
78 mb.wType = type;
79 mb.ActiveFlg = TRUE;
80 dwStyle = WS_POPUP | WS_DLGFRAME | WS_VISIBLE;
81 if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) == 0) dwStyle |= WS_CAPTION;
82 hWndOld = GetFocus();
83 hDlg = CreateWindow("MESSAGEBOX", title, dwStyle, 100, 150, 400, 120,
84 (HWND)NULL, (HMENU)NULL, hInst, (LPSTR)&mb);
85 if (hDlg == 0) return 0;
86 while(TRUE) {
87 if (!mb.ActiveFlg) break;
88 if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break;
89 TranslateMessage(&msg);
90 DispatchMessage(&msg);
92 SetFocus(hWndOld);
93 if (!UnregisterClass("MESSAGEBOX", hInst)) return 0;
94 #ifdef DEBUG_MSGBOX
95 printf( "MessageBox return %04X !\n", mb.wRetVal);
96 #endif
97 return(mb.wRetVal);
100 LPMSGBOX MsgBoxGetStorageHeader(HWND hwnd)
102 WND *wndPtr;
103 LPMSGBOX lpmb;
104 wndPtr = WIN_FindWndPtr(hwnd);
105 if (wndPtr == 0) {
106 printf("Bad Window handle on MessageBox !\n");
107 return 0;
109 lpmb = *((LPMSGBOX *)&wndPtr->wExtra[1]);
110 return lpmb;
116 LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam)
118 WND *wndPtr;
119 CREATESTRUCT *createStruct;
120 PAINTSTRUCT ps;
121 HDC hDC;
122 RECT rect;
123 LPMSGBOX lpmb;
124 LPMSGBOX lpmbInit;
125 BITMAP bm;
126 HBITMAP hBitMap;
127 HDC hMemDC;
128 HICON hIcon;
129 HINSTANCE hInst2;
130 int x;
131 switch(message) {
132 case WM_CREATE:
133 #ifdef DEBUG_MSGBOX
134 printf("MessageBox WM_CREATE !\n");
135 #endif
136 wndPtr = WIN_FindWndPtr(hWnd);
137 createStruct = (CREATESTRUCT *)lParam;
138 lpmbInit = (LPMSGBOX)createStruct->lpCreateParams;
139 if (lpmbInit == 0) break;
140 *((LPMSGBOX *)&wndPtr->wExtra[1]) = lpmbInit;
141 lpmb = MsgBoxGetStorageHeader(hWnd);
142 GetClientRect(hWnd, &rect);
143 CopyRect(&lpmb->rectStr, &rect);
144 lpmb->rectStr.bottom -= 32;
145 switch(lpmb->wType & MB_TYPEMASK) {
146 case MB_OK :
147 lpmb->hWndYes = CreateWindow("BUTTON", "&Ok",
148 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
149 rect.right / 2 - 30, rect.bottom - 25,
150 60, 18, hWnd, IDOK, wndPtr->hInstance, 0L);
151 break;
152 case MB_OKCANCEL :
153 lpmb->hWndYes = CreateWindow("BUTTON", "&Ok",
154 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
155 rect.right / 2 - 65, rect.bottom - 25,
156 60, 18, hWnd, IDOK, wndPtr->hInstance, 0L);
157 lpmb->hWndCancel = CreateWindow("BUTTON", "&Cancel",
158 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
159 rect.right / 2 + 5, rect.bottom - 25,
160 60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L);
161 break;
162 case MB_ABORTRETRYIGNORE :
163 lpmb->hWndYes = CreateWindow("BUTTON", "&Retry",
164 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
165 rect.right / 2 - 100, rect.bottom - 25,
166 60, 18, hWnd, IDRETRY, wndPtr->hInstance, 0L);
167 lpmb->hWndNo = CreateWindow("BUTTON", "&Ignore",
168 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
169 rect.right / 2 - 30, rect.bottom - 25,
170 60, 18, hWnd, IDIGNORE, wndPtr->hInstance, 0L);
171 lpmb->hWndCancel = CreateWindow("BUTTON", "&Abort",
172 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
173 rect.right / 2 + 40, rect.bottom - 25,
174 60, 18, hWnd, IDABORT, wndPtr->hInstance, 0L);
175 break;
176 case MB_YESNO :
177 lpmb->hWndYes = CreateWindow("BUTTON", "&Yes",
178 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
179 rect.right / 2 - 65, rect.bottom - 25,
180 60, 18, hWnd, IDYES, wndPtr->hInstance, 0L);
181 lpmb->hWndNo = CreateWindow("BUTTON", "&No",
182 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
183 rect.right / 2 + 5, rect.bottom - 25,
184 60, 18, hWnd, IDNO, wndPtr->hInstance, 0L);
185 break;
186 case MB_YESNOCANCEL :
187 lpmb->hWndYes = CreateWindow("BUTTON", "&Yes",
188 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
189 rect.right / 2 - 100, rect.bottom - 25,
190 60, 18, hWnd, IDYES, wndPtr->hInstance, 0L);
191 lpmb->hWndNo = CreateWindow("BUTTON", "&No",
192 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
193 rect.right / 2 - 30, rect.bottom - 25,
194 60, 18, hWnd, IDNO, wndPtr->hInstance, 0L);
195 lpmb->hWndCancel = CreateWindow("BUTTON", "&Cancel",
196 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
197 rect.right / 2 + 40, rect.bottom - 25,
198 60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L);
199 break;
201 switch(lpmb->wType & MB_ICONMASK) {
202 case MB_ICONEXCLAMATION:
203 printf("MsgBox LoadIcon Exclamation !\n");
204 lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_EXCLAMATION);
205 break;
206 case MB_ICONQUESTION:
207 printf("MsgBox LoadIcon Question !\n");
208 lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_QUESTION);
209 break;
210 case MB_ICONASTERISK:
211 printf("MsgBox LoadIcon Asterisk !\n");
212 lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_ASTERISK);
213 break;
214 case MB_ICONHAND:
215 printf("MsgBox LoadIcon Hand !\n");
216 lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_HAND);
217 break;
219 if (lpmb->hIcon != (HICON)NULL) {
220 SetRect(&lpmb->rectIcon, 16,
221 lpmb->rectStr.bottom / 2 - 16, 48,
222 lpmb->rectStr.bottom / 2 + 16);
223 lpmb->rectStr.left += 64;
225 break;
226 case WM_PAINT:
227 #ifdef DEBUG_MSGBOX
228 printf("MessageBox WM_PAINT !\n");
229 #endif
230 lpmb = MsgBoxGetStorageHeader(hWnd);
231 CopyRect(&rect, &lpmb->rectStr);
232 hDC = BeginPaint(hWnd, &ps);
233 if (lpmb->hIcon)
234 DrawIcon(hDC, lpmb->rectIcon.left,
235 lpmb->rectIcon.top, lpmb->hIcon);
236 DrawText(hDC, lpmb->Str, -1, &rect,
237 DT_CALCRECT | DT_CENTER | DT_WORDBREAK);
238 rect.top = lpmb->rectStr.bottom / 2 - rect.bottom / 2;
239 rect.bottom = lpmb->rectStr.bottom / 2 + rect.bottom / 2;
240 DrawText(hDC, lpmb->Str, -1, &rect, DT_CENTER | DT_WORDBREAK);
241 EndPaint(hWnd, &ps);
242 break;
243 case WM_DESTROY:
244 #ifdef DEBUG_MSGBOX
245 printf("MessageBox WM_DESTROY !\n");
246 #endif
247 ReleaseCapture();
248 lpmb = MsgBoxGetStorageHeader(hWnd);
249 lpmb->ActiveFlg = FALSE;
250 if (lpmb->hIcon) DestroyIcon(lpmb->hIcon);
251 if (lpmb->hWndYes) DestroyWindow(lpmb->hWndYes);
252 if (lpmb->hWndNo) DestroyWindow(lpmb->hWndNo);
253 if (lpmb->hWndCancel) DestroyWindow(lpmb->hWndCancel);
254 #ifdef DEBUG_MSGBOX
255 printf("MessageBox WM_DESTROY end !\n");
256 #endif
257 break;
258 case WM_COMMAND:
259 lpmb = MsgBoxGetStorageHeader(hWnd);
260 if (wParam < IDOK || wParam > IDNO) return(0);
261 lpmb->wRetVal = wParam;
262 #ifdef DEBUG_MSGBOX
263 printf("MessageBox sending WM_CLOSE !\n");
264 #endif
265 PostMessage(hWnd, WM_CLOSE, 0, 0L);
266 break;
267 case WM_CHAR:
268 lpmb = MsgBoxGetStorageHeader(hWnd);
269 if (wParam >= 'a' || wParam <= 'z') wParam -= 'a' - 'A';
270 switch(wParam) {
271 case 'Y':
272 lpmb->wRetVal = IDYES;
273 break;
274 case 'O':
275 lpmb->wRetVal = IDOK;
276 break;
277 case 'R':
278 lpmb->wRetVal = IDRETRY;
279 break;
280 case 'A':
281 lpmb->wRetVal = IDABORT;
282 break;
283 case 'N':
284 lpmb->wRetVal = IDNO;
285 break;
286 case 'I':
287 lpmb->wRetVal = IDIGNORE;
288 break;
289 case 'C':
290 case VK_ESCAPE:
291 lpmb->wRetVal = IDCANCEL;
292 break;
293 default:
294 return 0;
296 PostMessage(hWnd, WM_CLOSE, 0, 0L);
297 break;
298 default:
299 return DefWindowProc(hWnd, message, wParam, lParam );
301 return(0);
306 /*************************************************************************
307 * "About Wine..." Dialog Box
309 BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam)
311 HDC hDC;
312 HDC hMemDC;
313 PAINTSTRUCT ps;
314 int OldBackMode;
315 HFONT hOldFont;
316 RECT rect;
317 BITMAP bm;
318 int X;
319 OFSTRUCT ofstruct;
320 static LPSTR ptr;
321 static char str[256];
322 static HBITMAP hBitMap = 0;
323 static BOOL CreditMode;
324 static HANDLE hFile = 0;
325 switch (msg) {
326 case WM_INITDIALOG:
327 CreditMode = FALSE;
328 strcpy(str, "WINELOGO");
329 hBitMap = LoadBitmap((HINSTANCE)NULL, (LPSTR)str);
331 strcpy(str, "PROPOSED_LICENSE");
332 printf("str = '%s'\n", str);
333 hFile = OpenFile((LPSTR)str, &ofstruct, OF_READ);
334 ptr = (LPSTR)malloc(2048);
335 lseek(hFile, 0L, SEEK_SET);
336 _lread(hFile, ptr, 2000L);
337 close(hFile);
338 return TRUE;
339 case WM_PAINT:
340 hDC = BeginPaint(hDlg, &ps);
341 GetClientRect(hDlg, &rect);
342 if (CreditMode) {
343 FillRect(hDC, &rect, GetStockObject(WHITE_BRUSH));
344 InflateRect(&rect, -8, -8);
345 DrawText(hDC, ptr, -1, &rect, DT_LEFT | DT_WORDBREAK);
346 EndPaint(hDlg, &ps);
347 return TRUE;
349 FillRect(hDC, &rect, GetStockObject(GRAY_BRUSH));
350 InflateRect(&rect, -3, -3);
351 FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
352 InflateRect(&rect, -10, -10);
353 hMemDC = CreateCompatibleDC(hDC);
354 SelectObject(hMemDC, hBitMap);
355 GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
356 BitBlt(hDC, rect.left, rect.top, bm.bmWidth, bm.bmHeight,
357 hMemDC, 0, 0, SRCCOPY);
358 DeleteDC(hMemDC);
359 EndPaint(hDlg, &ps);
360 return TRUE;
361 case WM_COMMAND:
362 switch (wParam)
364 case IDYES:
365 if (!CreditMode) {
366 SetWindowPos(hDlg, (HWND)NULL, 0, 0, 640, 480,
367 SWP_NOMOVE | SWP_NOZORDER);
369 else {
370 SetWindowPos(hDlg, (HWND)NULL, 0, 0, 320, 250,
371 SWP_NOMOVE | SWP_NOZORDER);
373 CreditMode = !CreditMode;
374 ShowWindow(GetDlgItem(hDlg, IDYES), CreditMode ? SW_HIDE : SW_SHOW);
375 ShowWindow(GetDlgItem(hDlg, IDOK), CreditMode ? SW_HIDE : SW_SHOW);
376 InvalidateRect(hDlg, (LPRECT)NULL, TRUE);
377 UpdateWindow(hDlg);
378 return TRUE;
379 case IDCANCEL:
380 case IDOK:
381 CloseDLG: if (hBitMap != 0 ) DeleteObject(hBitMap);
382 if (ptr != NULL) free(ptr);
383 EndDialog(hDlg, TRUE);
384 return TRUE;
385 default:
386 return TRUE;
389 return FALSE;
393 /**************************************************************************
394 * FatalAppExit [USER.137]
397 void FatalAppExit(WORD wAction, LPSTR str)
399 MessageBox((HWND)NULL, str, NULL, MB_SYSTEMMODAL | MB_OK);
400 exit(1);