Release 940420
[wine/multimedia.git] / misc / message.c
blobc5459632468c88b29bf20a138bef9b114775c90d
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 if (wndPtr == NULL) {
58 hInst = hSysRes;
59 #ifdef DEBUG_MSGBOX
60 printf("MessageBox(NULL, '%s', '%s', %04X)\n", str, title, type);
61 #endif
63 else {
64 hInst = wndPtr->hInstance;
65 #ifdef DEBUG_MSGBOX
66 printf("MessageBox(%04X, '%s', '%s', %04X)\n", hWnd, str, title, type);
67 #endif
69 wndClass.style = CS_HREDRAW | CS_VREDRAW ;
70 wndClass.lpfnWndProc = (WNDPROC)SystemMessageBoxProc;
71 wndClass.cbClsExtra = 0;
72 wndClass.cbWndExtra = 0;
73 wndClass.hInstance = hInst;
74 wndClass.hIcon = (HICON)NULL;
75 wndClass.hCursor = LoadCursor((HANDLE)NULL, IDC_ARROW);
76 wndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
77 wndClass.lpszMenuName = NULL;
78 wndClass.lpszClassName = "MESSAGEBOX";
79 if (!RegisterClass(&wndClass)) {
80 printf("Unable to Register class 'MESSAGEBOX' !\n");
81 return 0;
83 memset(&mb, 0, sizeof(MSGBOX));
84 mb.Title = title;
85 mb.Str = str;
86 mb.wType = type;
87 mb.ActiveFlg = TRUE;
88 dwStyle = WS_POPUP | WS_DLGFRAME | WS_VISIBLE;
89 if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) == 0) dwStyle |= WS_CAPTION;
90 hWndOld = GetFocus();
91 hDlg = CreateWindow("MESSAGEBOX", title, dwStyle, 100, 150, 400, 120,
92 (HWND)NULL, (HMENU)NULL, hInst, (LPSTR)&mb);
93 if (hDlg == 0) {
94 printf("Unable to create 'MESSAGEBOX' window !\n");
95 return 0;
97 #ifdef DEBUG_MSGBOX
98 printf( "MessageBox // before Msg Loop !\n");
99 #endif
100 while(TRUE) {
101 if (!mb.ActiveFlg) break;
102 if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break;
103 TranslateMessage(&msg);
104 if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) != 0 &&
105 msg.hwnd != hDlg) {
106 switch(msg.message) {
107 case WM_KEYDOWN:
108 case WM_LBUTTONDOWN:
109 case WM_MBUTTONDOWN:
110 case WM_RBUTTONDOWN:
111 MessageBeep(0);
112 break;
115 DispatchMessage(&msg);
117 SetFocus(hWndOld);
118 if (!UnregisterClass("MESSAGEBOX", hInst)) return 0;
119 #ifdef DEBUG_MSGBOX
120 printf( "MessageBox return %04X !\n", mb.wRetVal);
121 #endif
122 return(mb.wRetVal);
126 LPMSGBOX MsgBoxGetStorageHeader(HWND hwnd)
128 WND *wndPtr;
129 LPMSGBOX lpmb;
130 wndPtr = WIN_FindWndPtr(hwnd);
131 if (wndPtr == 0) {
132 printf("Bad Window handle on MessageBox !\n");
133 return 0;
135 lpmb = *((LPMSGBOX *)&wndPtr->wExtra[1]);
136 return lpmb;
142 LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam)
144 WND *wndPtr;
145 CREATESTRUCT *createStruct;
146 PAINTSTRUCT ps;
147 HDC hDC;
148 DWORD OldTextColor;
149 RECT rect;
150 LPMSGBOX lpmb;
151 LPMSGBOX lpmbInit;
152 BITMAP bm;
153 HBITMAP hBitMap;
154 HDC hMemDC;
155 HICON hIcon;
156 HINSTANCE hInst2;
157 int x;
158 switch(message) {
159 case WM_CREATE:
160 #ifdef DEBUG_MSGBOX
161 printf("MessageBox WM_CREATE !\n");
162 #endif
163 wndPtr = WIN_FindWndPtr(hWnd);
164 createStruct = (CREATESTRUCT *)lParam;
165 lpmbInit = (LPMSGBOX)createStruct->lpCreateParams;
166 if (lpmbInit == 0) break;
167 *((LPMSGBOX *)&wndPtr->wExtra[1]) = lpmbInit;
168 lpmb = MsgBoxGetStorageHeader(hWnd);
169 GetClientRect(hWnd, &rect);
170 CopyRect(&lpmb->rectStr, &rect);
171 lpmb->rectStr.bottom -= 32;
172 switch(lpmb->wType & MB_TYPEMASK) {
173 case MB_OK :
174 lpmb->hWndYes = CreateWindow("BUTTON", "&Ok",
175 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
176 rect.right / 2 - 30, rect.bottom - 25,
177 60, 18, hWnd, IDOK, wndPtr->hInstance, 0L);
178 break;
179 case MB_OKCANCEL :
180 lpmb->hWndYes = CreateWindow("BUTTON", "&Ok",
181 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
182 rect.right / 2 - 65, rect.bottom - 25,
183 60, 18, hWnd, IDOK, wndPtr->hInstance, 0L);
184 lpmb->hWndCancel = CreateWindow("BUTTON", "&Cancel",
185 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
186 rect.right / 2 + 5, rect.bottom - 25,
187 60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L);
188 break;
189 case MB_ABORTRETRYIGNORE :
190 lpmb->hWndYes = CreateWindow("BUTTON", "&Retry",
191 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
192 rect.right / 2 - 100, rect.bottom - 25,
193 60, 18, hWnd, IDRETRY, wndPtr->hInstance, 0L);
194 lpmb->hWndNo = CreateWindow("BUTTON", "&Ignore",
195 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
196 rect.right / 2 - 30, rect.bottom - 25,
197 60, 18, hWnd, IDIGNORE, wndPtr->hInstance, 0L);
198 lpmb->hWndCancel = CreateWindow("BUTTON", "&Abort",
199 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
200 rect.right / 2 + 40, rect.bottom - 25,
201 60, 18, hWnd, IDABORT, wndPtr->hInstance, 0L);
202 break;
203 case MB_YESNO :
204 lpmb->hWndYes = CreateWindow("BUTTON", "&Yes",
205 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
206 rect.right / 2 - 65, rect.bottom - 25,
207 60, 18, hWnd, IDYES, wndPtr->hInstance, 0L);
208 lpmb->hWndNo = CreateWindow("BUTTON", "&No",
209 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
210 rect.right / 2 + 5, rect.bottom - 25,
211 60, 18, hWnd, IDNO, wndPtr->hInstance, 0L);
212 break;
213 case MB_YESNOCANCEL :
214 lpmb->hWndYes = CreateWindow("BUTTON", "&Yes",
215 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
216 rect.right / 2 - 100, rect.bottom - 25,
217 60, 18, hWnd, IDYES, wndPtr->hInstance, 0L);
218 lpmb->hWndNo = CreateWindow("BUTTON", "&No",
219 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
220 rect.right / 2 - 30, rect.bottom - 25,
221 60, 18, hWnd, IDNO, wndPtr->hInstance, 0L);
222 lpmb->hWndCancel = CreateWindow("BUTTON", "&Cancel",
223 WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON,
224 rect.right / 2 + 40, rect.bottom - 25,
225 60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L);
226 break;
228 switch(lpmb->wType & MB_ICONMASK) {
229 case MB_ICONEXCLAMATION:
230 printf("MsgBox LoadIcon Exclamation !\n");
231 lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_EXCLAMATION);
232 break;
233 case MB_ICONQUESTION:
234 printf("MsgBox LoadIcon Question !\n");
235 lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_QUESTION);
236 break;
237 case MB_ICONASTERISK:
238 printf("MsgBox LoadIcon Asterisk !\n");
239 lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_ASTERISK);
240 break;
241 case MB_ICONHAND:
242 printf("MsgBox LoadIcon Hand !\n");
243 lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_HAND);
244 break;
246 if (lpmb->hIcon != (HICON)NULL) {
247 SetRect(&lpmb->rectIcon, 16,
248 lpmb->rectStr.bottom / 2 - 16, 48,
249 lpmb->rectStr.bottom / 2 + 16);
250 lpmb->rectStr.left += 64;
252 break;
253 case WM_PAINT:
254 #ifdef DEBUG_MSGBOX
255 printf("MessageBox WM_PAINT !\n");
256 #endif
257 lpmb = MsgBoxGetStorageHeader(hWnd);
258 CopyRect(&rect, &lpmb->rectStr);
259 hDC = BeginPaint(hWnd, &ps);
260 OldTextColor = SetTextColor(hDC, 0x00000000);
261 if (lpmb->hIcon)
262 DrawIcon(hDC, lpmb->rectIcon.left,
263 lpmb->rectIcon.top, lpmb->hIcon);
264 DrawText(hDC, lpmb->Str, -1, &rect,
265 DT_CALCRECT | DT_CENTER | DT_WORDBREAK);
266 rect.top = lpmb->rectStr.bottom / 2 - rect.bottom / 2;
267 rect.bottom = lpmb->rectStr.bottom / 2 + rect.bottom / 2;
268 DrawText(hDC, lpmb->Str, -1, &rect, DT_CENTER | DT_WORDBREAK);
269 SetTextColor(hDC, OldTextColor);
270 EndPaint(hWnd, &ps);
271 #ifdef DEBUG_MSGBOX
272 printf("MessageBox End of WM_PAINT !\n");
273 #endif
274 break;
275 case WM_DESTROY:
276 #ifdef DEBUG_MSGBOX
277 printf("MessageBox WM_DESTROY !\n");
278 #endif
279 ReleaseCapture();
280 lpmb = MsgBoxGetStorageHeader(hWnd);
281 lpmb->ActiveFlg = FALSE;
282 if (lpmb->hIcon) DestroyIcon(lpmb->hIcon);
283 if (lpmb->hWndYes) DestroyWindow(lpmb->hWndYes);
284 if (lpmb->hWndNo) DestroyWindow(lpmb->hWndNo);
285 if (lpmb->hWndCancel) DestroyWindow(lpmb->hWndCancel);
286 #ifdef DEBUG_MSGBOX
287 printf("MessageBox WM_DESTROY end !\n");
288 #endif
289 break;
290 case WM_COMMAND:
291 lpmb = MsgBoxGetStorageHeader(hWnd);
292 if (wParam < IDOK || wParam > IDNO) return(0);
293 lpmb->wRetVal = wParam;
294 #ifdef DEBUG_MSGBOX
295 printf("MessageBox sending WM_CLOSE !\n");
296 #endif
297 PostMessage(hWnd, WM_CLOSE, 0, 0L);
298 break;
299 case WM_CHAR:
300 lpmb = MsgBoxGetStorageHeader(hWnd);
301 if (wParam >= 'a' || wParam <= 'z') wParam -= 'a' - 'A';
302 switch(wParam) {
303 case 'Y':
304 lpmb->wRetVal = IDYES;
305 break;
306 case 'O':
307 lpmb->wRetVal = IDOK;
308 break;
309 case 'R':
310 lpmb->wRetVal = IDRETRY;
311 break;
312 case 'A':
313 lpmb->wRetVal = IDABORT;
314 break;
315 case 'N':
316 lpmb->wRetVal = IDNO;
317 break;
318 case 'I':
319 lpmb->wRetVal = IDIGNORE;
320 break;
321 case 'C':
322 case VK_ESCAPE:
323 lpmb->wRetVal = IDCANCEL;
324 break;
325 default:
326 return 0;
328 PostMessage(hWnd, WM_CLOSE, 0, 0L);
329 break;
330 default:
331 return DefWindowProc(hWnd, message, wParam, lParam );
333 return(0);
338 /*************************************************************************
339 * "About Wine..." Dialog Box
341 BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam)
343 HDC hDC;
344 HDC hMemDC;
345 PAINTSTRUCT ps;
346 int OldBackMode;
347 HFONT hOldFont;
348 RECT rect;
349 BITMAP bm;
350 int X;
351 OFSTRUCT ofstruct;
352 static LPSTR ptr;
353 static char str[256];
354 static HBITMAP hBitMap = 0;
355 static BOOL CreditMode;
356 static HANDLE hFile = 0;
357 switch (msg) {
358 case WM_INITDIALOG:
359 CreditMode = FALSE;
360 strcpy(str, "WINELOGO");
361 hBitMap = LoadBitmap((HINSTANCE)NULL, (LPSTR)str);
363 strcpy(str, "PROPOSED_LICENSE");
364 printf("str = '%s'\n", str);
365 hFile = OpenFile((LPSTR)str, &ofstruct, OF_READ);
366 ptr = (LPSTR)malloc(2048);
367 lseek(hFile, 0L, SEEK_SET);
368 _lread(hFile, ptr, 2000L);
369 close(hFile);
370 return TRUE;
371 case WM_PAINT:
372 hDC = BeginPaint(hDlg, &ps);
373 GetClientRect(hDlg, &rect);
374 if (CreditMode) {
375 FillRect(hDC, &rect, GetStockObject(WHITE_BRUSH));
376 InflateRect(&rect, -8, -8);
377 DrawText(hDC, ptr, -1, &rect, DT_LEFT | DT_WORDBREAK);
378 EndPaint(hDlg, &ps);
379 return TRUE;
381 FillRect(hDC, &rect, GetStockObject(GRAY_BRUSH));
382 InflateRect(&rect, -3, -3);
383 FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
384 InflateRect(&rect, -10, -10);
385 hMemDC = CreateCompatibleDC(hDC);
386 SelectObject(hMemDC, hBitMap);
387 GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
388 BitBlt(hDC, rect.left, rect.top, bm.bmWidth, bm.bmHeight,
389 hMemDC, 0, 0, SRCCOPY);
390 DeleteDC(hMemDC);
391 EndPaint(hDlg, &ps);
392 return TRUE;
393 case WM_COMMAND:
394 switch (wParam)
396 case IDYES:
397 if (!CreditMode) {
398 SetWindowPos(hDlg, (HWND)NULL, 0, 0, 640, 480,
399 SWP_NOMOVE | SWP_NOZORDER);
401 else {
402 SetWindowPos(hDlg, (HWND)NULL, 0, 0, 320, 250,
403 SWP_NOMOVE | SWP_NOZORDER);
405 CreditMode = !CreditMode;
406 ShowWindow(GetDlgItem(hDlg, IDYES), CreditMode ? SW_HIDE : SW_SHOW);
407 ShowWindow(GetDlgItem(hDlg, IDOK), CreditMode ? SW_HIDE : SW_SHOW);
408 InvalidateRect(hDlg, (LPRECT)NULL, TRUE);
409 UpdateWindow(hDlg);
410 return TRUE;
411 case IDCANCEL:
412 case IDOK:
413 CloseDLG: if (hBitMap != 0 ) DeleteObject(hBitMap);
414 if (ptr != NULL) free(ptr);
415 EndDialog(hDlg, TRUE);
416 return TRUE;
417 default:
418 return TRUE;
421 return FALSE;
425 /**************************************************************************
426 * FatalAppExit [USER.137]
429 void FatalAppExit(WORD wAction, LPSTR str)
431 MessageBox((HWND)NULL, str, NULL, MB_SYSTEMMODAL | MB_OK);
432 exit(1);