2 * 'Wine' MessageBox function handling
4 * Copyright 1993 Martin Ayotte
6 static char Copyright[] = "Copyright Martin Ayotte, 1993";
13 #include <sys/types.h>
23 /* #define DEBUG_MSGBOX */
28 * Defaults for button-texts
31 ButtonTexts ButtonText
= { /* FIXME: Norwegian Translation missing */
38 { "&Wiederholen", 'W' },
39 { "&Ignorieren", 'I' }
51 extern HBITMAP hUpArrow
;
53 typedef struct tagMSGBOX
{
66 typedef MSGBOX FAR
* LPMSGBOX
;
68 LONG
SystemMessageBoxProc(HWND hwnd
, WORD message
, WORD wParam
, LONG lParam
);
70 /**************************************************************************
74 int MessageBox(HWND hWnd
, LPSTR str
, LPSTR title
, WORD type
)
81 HANDLE hClassName
, hMsg
;
88 wndPtr
= WIN_FindWndPtr(hWnd
);
91 dprintf_msgbox(stddeb
,"MessageBox(NULL, str='%s', title='%s', %04X)\n",
95 hInst
= wndPtr
->hInstance
;
96 dprintf_msgbox(stddeb
,"MessageBox(%04X, str='%s', title='%s', %04X)\n",
97 hWnd
, str
, title
, type
);
99 lpmb
= (LPMSGBOX
) malloc(sizeof(MSGBOX
));
100 memset(lpmb
, 0, sizeof(MSGBOX
));
101 /* lpmb->Title = title;*/
102 lpmb
->Title
= (LPSTR
) malloc(strlen(title
) + 1);
103 strcpy(lpmb
->Title
, title
);
104 /* lpmb->Str = str;*/
107 lpmb
->Str
= (LPSTR
) malloc(strlen(str
) + 1);
108 strcpy(lpmb
->Str
, str
);
112 lpmb
->Str
= (LPSTR
) malloc(8);
113 strcpy(lpmb
->Str
, "Message");
116 lpmb
->ActiveFlg
= TRUE
;
117 wndClass
.style
= CS_HREDRAW
| CS_VREDRAW
;
118 wndClass
.lpfnWndProc
= (WNDPROC
)SystemMessageBoxProc
;
119 wndClass
.cbClsExtra
= 0;
120 wndClass
.cbWndExtra
= 4;
121 wndClass
.hInstance
= hInst
;
122 wndClass
.hIcon
= (HICON
)NULL
;
123 wndClass
.hCursor
= LoadCursor((HANDLE
)NULL
, IDC_ARROW
);
124 wndClass
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
125 wndClass
.lpszMenuName
= NULL
;
126 hClassName
= USER_HEAP_ALLOC( 20 );
127 strcpy( USER_HEAP_LIN_ADDR( hClassName
), "MESSAGEBOX" );
128 hMsg
= USER_HEAP_ALLOC( sizeof(MSG
) );
129 msg
= (MSG
*) USER_HEAP_LIN_ADDR( hMsg
);
130 wndClass
.lpszClassName
= (LPSTR
)USER_HEAP_SEG_ADDR( hClassName
);
131 dprintf_msgbox(stddeb
, "MessageBox // before RegisterClass, '%s' '%s' !\n", str
, title
);
132 if (!RegisterClass(&wndClass
)) {
133 printf("Unable to Register class 'MESSAGEBOX' !\n");
134 if (lpmb
!= NULL
) free(lpmb
);
137 USER_HEAP_FREE( hClassName
);
138 dwStyle
= WS_POPUP
| WS_DLGFRAME
| WS_VISIBLE
;
139 if ((type
& (MB_SYSTEMMODAL
| MB_TASKMODAL
)) == 0) dwStyle
|= WS_CAPTION
;
140 hWndOld
= GetFocus();
141 hDlg
= CreateWindow("MESSAGEBOX", lpmb
->Title
, dwStyle
, 100, 150, 400, 160,
142 (HWND
)NULL
, (HMENU
)NULL
, hInst
, (SEGPTR
)lpmb
);
144 printf("Unable to create 'MESSAGEBOX' window !\n");
145 if (lpmb
!= NULL
) free(lpmb
);
148 dprintf_msgbox(stddeb
, "MessageBox // before Msg Loop !\n");
150 if (!lpmb
->ActiveFlg
) break;
151 if (!GetMessage( USER_HEAP_SEG_ADDR(hMsg
),
152 (HWND
)NULL
, 0, 0)) break;
153 TranslateMessage(msg
);
154 if ((type
& (MB_SYSTEMMODAL
| MB_TASKMODAL
)) != 0 &&
156 switch(msg
->message
) {
165 DispatchMessage(msg
);
167 USER_HEAP_FREE(hMsg
);
169 nRet
= lpmb
->wRetVal
;
170 if (lpmb
!= NULL
) free(lpmb
);
171 if (!UnregisterClass("MESSAGEBOX", hInst
)) return 0;
172 dprintf_msgbox(stddeb
, "MessageBox return %04X !\n", nRet
);
177 LPMSGBOX
MsgBoxGetStorageHeader(HWND hwnd
)
181 wndPtr
= WIN_FindWndPtr(hwnd
);
183 printf("Bad Window handle on MessageBox !\n");
186 lpmb
= *((LPMSGBOX
*)wndPtr
->wExtra
);
193 LONG
SystemMessageBoxProc(HWND hWnd
, WORD message
, WORD wParam
, LONG lParam
)
196 CREATESTRUCT
*createStruct
;
205 dprintf_msgbox(stddeb
, "MessageBox WM_CREATE hWnd=%04X !\n", hWnd
);
206 wndPtr
= WIN_FindWndPtr(hWnd
);
207 createStruct
= (CREATESTRUCT
*)PTR_SEG_TO_LIN(lParam
);
208 lpmb
= (LPMSGBOX
)createStruct
->lpCreateParams
;
209 if (lpmb
== NULL
) break;
210 *((LPMSGBOX
*)wndPtr
->wExtra
) = lpmb
;
211 dprintf_msgbox(stddeb
, "MessageBox WM_CREATE title='%s' str='%s' !\n",
212 lpmb
->Title
, lpmb
->Str
);
213 GetClientRect(hWnd
, &rect
);
214 CopyRect(&lpmb
->rectStr
, &rect
);
215 lpmb
->rectStr
.bottom
-= 32;
216 switch(lpmb
->wType
& MB_TYPEMASK
) {
218 lpmb
->hWndYes
= CreateWindow("BUTTON", ButtonText
.Ok
.Label
,
219 WS_CHILD
| WS_CLIPCHILDREN
| WS_VISIBLE
| BS_PUSHBUTTON
,
220 rect
.right
/ 2 - 30, rect
.bottom
- 25,
221 60, 18, hWnd
, IDOK
, wndPtr
->hInstance
, 0L);
224 lpmb
->hWndYes
= CreateWindow("BUTTON", ButtonText
.Ok
.Label
,
225 WS_CHILD
| WS_CLIPCHILDREN
| WS_VISIBLE
| BS_PUSHBUTTON
,
226 rect
.right
/ 2 - 65, rect
.bottom
- 25,
227 60, 18, hWnd
, IDOK
, wndPtr
->hInstance
, 0L);
228 lpmb
->hWndCancel
= CreateWindow("BUTTON", ButtonText
.Cancel
.Label
,
229 WS_CHILD
| WS_CLIPCHILDREN
| WS_VISIBLE
| BS_PUSHBUTTON
,
230 rect
.right
/ 2 + 5, rect
.bottom
- 25,
231 60, 18, hWnd
, IDCANCEL
, wndPtr
->hInstance
, 0L);
233 case MB_ABORTRETRYIGNORE
:
234 lpmb
->hWndYes
= CreateWindow("BUTTON", ButtonText
.Retry
.Label
,
235 WS_CHILD
| WS_CLIPCHILDREN
| WS_VISIBLE
| BS_PUSHBUTTON
,
236 rect
.right
/ 2 - 100, rect
.bottom
- 25,
237 60, 18, hWnd
, IDRETRY
, wndPtr
->hInstance
, 0L);
238 lpmb
->hWndNo
= CreateWindow("BUTTON", ButtonText
.Ignore
.Label
,
239 WS_CHILD
| WS_CLIPCHILDREN
| WS_VISIBLE
| BS_PUSHBUTTON
,
240 rect
.right
/ 2 - 30, rect
.bottom
- 25,
241 60, 18, hWnd
, IDIGNORE
, wndPtr
->hInstance
, 0L);
242 lpmb
->hWndCancel
= CreateWindow("BUTTON", ButtonText
.Abort
.Label
,
243 WS_CHILD
| WS_CLIPCHILDREN
| WS_VISIBLE
| BS_PUSHBUTTON
,
244 rect
.right
/ 2 + 40, rect
.bottom
- 25,
245 60, 18, hWnd
, IDABORT
, wndPtr
->hInstance
, 0L);
248 lpmb
->hWndYes
= CreateWindow("BUTTON", ButtonText
.Yes
.Label
,
249 WS_CHILD
| WS_CLIPCHILDREN
| WS_VISIBLE
| BS_PUSHBUTTON
,
250 rect
.right
/ 2 - 65, rect
.bottom
- 25,
251 60, 18, hWnd
, IDYES
, wndPtr
->hInstance
, 0L);
252 lpmb
->hWndNo
= CreateWindow("BUTTON", ButtonText
.No
.Label
,
253 WS_CHILD
| WS_CLIPCHILDREN
| WS_VISIBLE
| BS_PUSHBUTTON
,
254 rect
.right
/ 2 + 5, rect
.bottom
- 25,
255 60, 18, hWnd
, IDNO
, wndPtr
->hInstance
, 0L);
257 case MB_YESNOCANCEL
:
258 lpmb
->hWndYes
= CreateWindow("BUTTON", ButtonText
.Yes
.Label
,
259 WS_CHILD
| WS_CLIPCHILDREN
| WS_VISIBLE
| BS_PUSHBUTTON
,
260 rect
.right
/ 2 - 100, rect
.bottom
- 25,
261 60, 18, hWnd
, IDYES
, wndPtr
->hInstance
, 0L);
262 lpmb
->hWndNo
= CreateWindow("BUTTON", ButtonText
.No
.Label
,
263 WS_CHILD
| WS_CLIPCHILDREN
| WS_VISIBLE
| BS_PUSHBUTTON
,
264 rect
.right
/ 2 - 30, rect
.bottom
- 25,
265 60, 18, hWnd
, IDNO
, wndPtr
->hInstance
, 0L);
266 lpmb
->hWndCancel
= CreateWindow("BUTTON", ButtonText
.Cancel
.Label
,
267 WS_CHILD
| WS_CLIPCHILDREN
| WS_VISIBLE
| BS_PUSHBUTTON
,
268 rect
.right
/ 2 + 40, rect
.bottom
- 25,
269 60, 18, hWnd
, IDCANCEL
, wndPtr
->hInstance
, 0L);
272 switch(lpmb
->wType
& MB_ICONMASK
) {
273 case MB_ICONEXCLAMATION
:
274 printf("MsgBox LoadIcon Exclamation !\n");
275 lpmb
->hIcon
= LoadIcon((HINSTANCE
)NULL
, IDI_EXCLAMATION
);
277 case MB_ICONQUESTION
:
278 printf("MsgBox LoadIcon Question !\n");
279 lpmb
->hIcon
= LoadIcon((HINSTANCE
)NULL
, IDI_QUESTION
);
281 case MB_ICONASTERISK
:
282 printf("MsgBox LoadIcon Asterisk !\n");
283 lpmb
->hIcon
= LoadIcon((HINSTANCE
)NULL
, IDI_ASTERISK
);
286 printf("MsgBox LoadIcon Hand !\n");
287 lpmb
->hIcon
= LoadIcon((HINSTANCE
)NULL
, IDI_HAND
);
290 if (lpmb
->hIcon
!= (HICON
)NULL
) {
291 SetRect(&lpmb
->rectIcon
, 16,
292 lpmb
->rectStr
.bottom
/ 2 - 16, 48,
293 lpmb
->rectStr
.bottom
/ 2 + 16);
294 lpmb
->rectStr
.left
+= 64;
298 dprintf_msgbox(stddeb
, "MessageBox WM_SHOWWINDOW hWnd=%04X !\n", hWnd
);
299 if (!(wParam
== 0 && lParam
== 0L)) {
300 InvalidateRect(hWnd
, NULL
, TRUE
);
304 dprintf_msgbox(stddeb
, "MessageBox WM_PAINT hWnd=%04X !\n", hWnd
);
305 lpmb
= MsgBoxGetStorageHeader(hWnd
);
306 if (lpmb
== NULL
) break;
307 if (!lpmb
->ActiveFlg
) break;
308 hDC
= BeginPaint(hWnd
, &ps
);
310 printf("MessageBox WM_PAINT // BeginPaint returned BAD hDC !\n");
313 GetClientRect(hWnd
, &rect
);
314 FillRect(hDC
, &rect
, GetStockObject(WHITE_BRUSH
));
315 CopyRect(&rect
, &lpmb
->rectStr
);
316 OldTextColor
= SetTextColor(hDC
, 0x00000000);
318 DrawIcon(hDC
, lpmb
->rectIcon
.left
,
319 lpmb
->rectIcon
.top
, lpmb
->hIcon
);
320 DrawText(hDC
, lpmb
->Str
, -1, &rect
,
321 DT_CALCRECT
| DT_LEFT
| DT_VCENTER
| DT_WORDBREAK
);
322 rect
.top
= lpmb
->rectStr
.bottom
/ 2 - rect
.bottom
/ 2;
323 rect
.bottom
= lpmb
->rectStr
.bottom
/ 2 + rect
.bottom
/ 2;
324 DrawText(hDC
, lpmb
->Str
, -1, &rect
, DT_LEFT
| DT_VCENTER
| DT_WORDBREAK
);
325 SetTextColor(hDC
, OldTextColor
);
327 dprintf_msgbox(stddeb
, "MessageBox End of WM_PAINT !\n");
330 dprintf_msgbox(stddeb
, "MessageBox WM_DESTROY !\n");
332 lpmb
= MsgBoxGetStorageHeader(hWnd
);
333 if (lpmb
== NULL
) break;
334 if (lpmb
->hIcon
) DestroyIcon(lpmb
->hIcon
);
335 if (lpmb
->hWndYes
) DestroyWindow(lpmb
->hWndYes
);
336 if (lpmb
->hWndNo
) DestroyWindow(lpmb
->hWndNo
);
337 if (lpmb
->hWndCancel
) DestroyWindow(lpmb
->hWndCancel
);
338 dprintf_msgbox(stddeb
, "MessageBox WM_DESTROY end !\n");
339 lpmb
->ActiveFlg
= FALSE
;
342 lpmb
= MsgBoxGetStorageHeader(hWnd
);
343 if (lpmb
== NULL
) break;
344 if (wParam
< IDOK
|| wParam
> IDNO
) return(0);
345 lpmb
->wRetVal
= wParam
;
346 dprintf_msgbox(stddeb
, "MessageBox sending WM_CLOSE !\n");
347 PostMessage(hWnd
, WM_CLOSE
, 0, 0L);
350 lpmb
= MsgBoxGetStorageHeader(hWnd
);
351 /* if (wParam >= 'a' || wParam <= 'z') wParam -= 'a' - 'A'; */
352 wParam
= toupper(wParam
);
353 if (wParam
== ButtonText
.Yes
.Hotkey
)
354 lpmb
->wRetVal
= IDYES
;
355 else if (wParam
== ButtonText
.Ok
.Hotkey
)
356 lpmb
->wRetVal
= IDOK
;
357 else if (wParam
== ButtonText
.Retry
.Hotkey
)
358 lpmb
->wRetVal
= IDRETRY
;
359 else if (wParam
== ButtonText
.Abort
.Hotkey
)
360 lpmb
->wRetVal
= IDABORT
;
361 else if (wParam
== ButtonText
.No
.Hotkey
)
362 lpmb
->wRetVal
= IDNO
;
363 else if (wParam
== ButtonText
.Ignore
.Hotkey
)
364 lpmb
->wRetVal
= IDIGNORE
;
365 else if ((wParam
== ButtonText
.Ok
.Hotkey
) || (wParam
== VK_ESCAPE
))
366 lpmb
->wRetVal
= IDCANCEL
;
369 if (lpmb
== NULL
) break;
370 ShowWindow(hWnd
, SW_HIDE
);
371 PostMessage(hWnd
, WM_CLOSE
, 0, 0L);
374 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
381 /*************************************************************************
382 * "About Wine..." Dialog Box
384 BOOL FAR PASCAL
AboutWine_Proc(HWND hDlg
, WORD msg
, WORD wParam
, LONG lParam
)
394 static char str
[256];
395 static HBITMAP hBitMap
= 0;
396 static BOOL CreditMode
;
397 static HANDLE hFile
= 0;
401 strcpy(str
, "WINELOGO");
402 hBitMap
= LoadBitmap((HINSTANCE
)NULL
, (LPSTR
)str
);
404 strcpy(str
, "LICENSE");
405 printf("str = '%s'\n", str
);
406 hFile
= OpenFile((LPSTR
)str
, &ofstruct
, OF_READ
);
407 ptr
= (LPSTR
)malloc(2048);
408 lseek(hFile
, 0L, SEEK_SET
);
409 _lread(hFile
, ptr
, 2000L);
413 hDC
= BeginPaint(hDlg
, &ps
);
414 GetClientRect(hDlg
, &rect
);
416 FillRect(hDC
, &rect
, GetStockObject(WHITE_BRUSH
));
417 InflateRect(&rect
, -8, -8);
418 DrawText(hDC
, ptr
, -1, &rect
, DT_LEFT
| DT_WORDBREAK
);
422 FillRect(hDC
, &rect
, GetStockObject(GRAY_BRUSH
));
423 InflateRect(&rect
, -3, -3);
424 FrameRect(hDC
, &rect
, GetStockObject(BLACK_BRUSH
));
425 InflateRect(&rect
, -10, -10);
426 hMemDC
= CreateCompatibleDC(hDC
);
427 hbmpOld
= SelectObject(hMemDC
, hBitMap
);
428 GetObject(hBitMap
, sizeof(BITMAP
), (LPSTR
)&bm
);
429 BitBlt(hDC
, rect
.left
, rect
.top
, bm
.bmWidth
, bm
.bmHeight
,
430 hMemDC
, 0, 0, SRCCOPY
);
431 SelectObject( hMemDC
, hbmpOld
);
440 SetWindowPos(hDlg
, (HWND
)NULL
, 0, 0, 640, 480,
441 SWP_NOMOVE
| SWP_NOZORDER
);
444 SetWindowPos(hDlg
, (HWND
)NULL
, 0, 0, 320, 250,
445 SWP_NOMOVE
| SWP_NOZORDER
);
447 CreditMode
= !CreditMode
;
448 ShowWindow(GetDlgItem(hDlg
, IDYES
), CreditMode
? SW_HIDE
: SW_SHOW
);
449 ShowWindow(GetDlgItem(hDlg
, IDOK
), CreditMode
? SW_HIDE
: SW_SHOW
);
450 InvalidateRect(hDlg
, (LPRECT
)NULL
, TRUE
);
455 if (hBitMap
!= 0 ) DeleteObject(hBitMap
);
456 if (ptr
!= NULL
) free(ptr
);
457 EndDialog(hDlg
, TRUE
);
467 /**************************************************************************
468 * FatalAppExit [USER.137]
471 void FatalAppExit(WORD wAction
, LPSTR str
)
473 MessageBox((HWND
)NULL
, str
, NULL
, MB_SYSTEMMODAL
| MB_OK
);