/* * 'Wine' MessageBox function handling * * Copyright 1993 Martin Ayotte * static char Copyright[] = "Copyright Martin Ayotte, 1993"; */ #include #include #include #include #include #include #include #include #include #include "heap.h" #include "library.h" #include "win.h" #include "texts.h" #include "stddebug.h" /* #define DEBUG_MSGBOX */ #include "debug.h" /* * Defaults for button-texts */ ButtonTexts ButtonText = { "&Yes", 'Y', "&No", 'N', "&Ok", 'O', "&Cancel", 'C', "&Abort", 'A', "&Retry", 'R', "&Ignore", 'I' }; extern HBITMAP hUpArrow; typedef struct tagMSGBOX { LPSTR Title; LPSTR Str; WORD wType; WORD wRetVal; BOOL ActiveFlg; HWND hWndYes; HWND hWndNo; HWND hWndCancel; HICON hIcon; RECT rectIcon; RECT rectStr; } MSGBOX; typedef MSGBOX FAR* LPMSGBOX; LONG SystemMessageBoxProc(HWND hwnd, WORD message, WORD wParam, LONG lParam); /************************************************************************** * MessageBox [USER.1] */ int MessageBox(HWND hWnd, LPSTR str, LPSTR title, WORD type) { HWND hDlg, hWndOld; WND *wndPtr; WNDCLASS wndClass; MSG msg; LPMSGBOX lpmb; DWORD dwStyle; HINSTANCE hInst; int nRet; if (title == NULL) title = "Error"; wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr == NULL) { hInst = hSysRes; dprintf_msgbox(stddeb,"MessageBox(NULL, str='%s', title='%s', %04X)\n", str, title, type); } else { hInst = wndPtr->hInstance; dprintf_msgbox(stddeb,"MessageBox(%04X, str='%s', title='%s', %04X)\n", hWnd, str, title, type); } lpmb = (LPMSGBOX) malloc(sizeof(MSGBOX)); memset(lpmb, 0, sizeof(MSGBOX)); /* lpmb->Title = title;*/ lpmb->Title = (LPSTR) malloc(strlen(title) + 1); strcpy(lpmb->Title, title); /* lpmb->Str = str;*/ if (str && *str) { lpmb->Str = (LPSTR) malloc(strlen(str) + 1); strcpy(lpmb->Str, str); } else { lpmb->Str = (LPSTR) malloc(8); strcpy(lpmb->Str, "Message"); } lpmb->wType = type; lpmb->ActiveFlg = TRUE; wndClass.style = CS_HREDRAW | CS_VREDRAW ; wndClass.lpfnWndProc = (WNDPROC)SystemMessageBoxProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hInst; wndClass.hIcon = (HICON)NULL; wndClass.hCursor = LoadCursor((HANDLE)NULL, IDC_ARROW); wndClass.hbrBackground = GetStockObject(WHITE_BRUSH); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = "MESSAGEBOX"; dprintf_msgbox(stddeb, "MessageBox // before RegisterClass, '%s' '%s' !\n", str, title); if (!RegisterClass(&wndClass)) { printf("Unable to Register class 'MESSAGEBOX' !\n"); if (lpmb != NULL) free(lpmb); return 0; } dwStyle = WS_POPUP | WS_DLGFRAME | WS_VISIBLE; if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) == 0) dwStyle |= WS_CAPTION; hWndOld = GetFocus(); hDlg = CreateWindow("MESSAGEBOX", lpmb->Title, dwStyle, 100, 150, 400, 160, (HWND)NULL, (HMENU)NULL, hInst, (LPSTR)lpmb); if (hDlg == 0) { printf("Unable to create 'MESSAGEBOX' window !\n"); if (lpmb != NULL) free(lpmb); return 0; } dprintf_msgbox(stddeb, "MessageBox // before Msg Loop !\n"); while(TRUE) { if (!lpmb->ActiveFlg) break; if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break; TranslateMessage(&msg); if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) != 0 && msg.hwnd != hDlg) { switch(msg.message) { case WM_KEYDOWN: case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: MessageBeep(0); break; } } DispatchMessage(&msg); } SetFocus(hWndOld); nRet = lpmb->wRetVal; if (lpmb != NULL) free(lpmb); if (!UnregisterClass("MESSAGEBOX", hInst)) return 0; dprintf_msgbox(stddeb, "MessageBox return %04X !\n", nRet); return(nRet); } LPMSGBOX MsgBoxGetStorageHeader(HWND hwnd) { WND *wndPtr; LPMSGBOX lpmb; wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr == 0) { printf("Bad Window handle on MessageBox !\n"); return 0; } lpmb = *((LPMSGBOX *)&wndPtr->wExtra[1]); return lpmb; } LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) { WND *wndPtr; CREATESTRUCT *createStruct; PAINTSTRUCT ps; HDC hDC; DWORD OldTextColor; RECT rect; LPMSGBOX lpmb; switch(message) { case WM_CREATE: dprintf_msgbox(stddeb, "MessageBox WM_CREATE hWnd=%04X !\n", hWnd); wndPtr = WIN_FindWndPtr(hWnd); createStruct = (CREATESTRUCT *)lParam; lpmb = (LPMSGBOX)createStruct->lpCreateParams; if (lpmb == NULL) break; *((LPMSGBOX *)&wndPtr->wExtra[1]) = lpmb; dprintf_msgbox(stddeb, "MessageBox WM_CREATE title='%s' str='%s' !\n", lpmb->Title, lpmb->Str); GetClientRect(hWnd, &rect); CopyRect(&lpmb->rectStr, &rect); lpmb->rectStr.bottom -= 32; switch(lpmb->wType & MB_TYPEMASK) { case MB_OK : lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Ok.Label, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, rect.right / 2 - 30, rect.bottom - 25, 60, 18, hWnd, IDOK, wndPtr->hInstance, 0L); break; case MB_OKCANCEL : lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Ok.Label, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, rect.right / 2 - 65, rect.bottom - 25, 60, 18, hWnd, IDOK, wndPtr->hInstance, 0L); lpmb->hWndCancel = CreateWindow("BUTTON", ButtonText.Cancel.Label, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, rect.right / 2 + 5, rect.bottom - 25, 60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L); break; case MB_ABORTRETRYIGNORE : lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Retry.Label, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, rect.right / 2 - 100, rect.bottom - 25, 60, 18, hWnd, IDRETRY, wndPtr->hInstance, 0L); lpmb->hWndNo = CreateWindow("BUTTON", ButtonText.Ignore.Label, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, rect.right / 2 - 30, rect.bottom - 25, 60, 18, hWnd, IDIGNORE, wndPtr->hInstance, 0L); lpmb->hWndCancel = CreateWindow("BUTTON", ButtonText.Abort.Label, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, rect.right / 2 + 40, rect.bottom - 25, 60, 18, hWnd, IDABORT, wndPtr->hInstance, 0L); break; case MB_YESNO : lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Yes.Label, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, rect.right / 2 - 65, rect.bottom - 25, 60, 18, hWnd, IDYES, wndPtr->hInstance, 0L); lpmb->hWndNo = CreateWindow("BUTTON", ButtonText.No.Label, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, rect.right / 2 + 5, rect.bottom - 25, 60, 18, hWnd, IDNO, wndPtr->hInstance, 0L); break; case MB_YESNOCANCEL : lpmb->hWndYes = CreateWindow("BUTTON", ButtonText.Yes.Label, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, rect.right / 2 - 100, rect.bottom - 25, 60, 18, hWnd, IDYES, wndPtr->hInstance, 0L); lpmb->hWndNo = CreateWindow("BUTTON", ButtonText.No.Label, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, rect.right / 2 - 30, rect.bottom - 25, 60, 18, hWnd, IDNO, wndPtr->hInstance, 0L); lpmb->hWndCancel = CreateWindow("BUTTON", ButtonText.Cancel.Label, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_PUSHBUTTON, rect.right / 2 + 40, rect.bottom - 25, 60, 18, hWnd, IDCANCEL, wndPtr->hInstance, 0L); break; } switch(lpmb->wType & MB_ICONMASK) { case MB_ICONEXCLAMATION: printf("MsgBox LoadIcon Exclamation !\n"); lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_EXCLAMATION); break; case MB_ICONQUESTION: printf("MsgBox LoadIcon Question !\n"); lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_QUESTION); break; case MB_ICONASTERISK: printf("MsgBox LoadIcon Asterisk !\n"); lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_ASTERISK); break; case MB_ICONHAND: printf("MsgBox LoadIcon Hand !\n"); lpmb->hIcon = LoadIcon((HINSTANCE)NULL, IDI_HAND); break; } if (lpmb->hIcon != (HICON)NULL) { SetRect(&lpmb->rectIcon, 16, lpmb->rectStr.bottom / 2 - 16, 48, lpmb->rectStr.bottom / 2 + 16); lpmb->rectStr.left += 64; } break; case WM_SHOWWINDOW: dprintf_msgbox(stddeb, "MessageBox WM_SHOWWINDOW hWnd=%04X !\n", hWnd); if (!(wParam == 0 && lParam == 0L)) { InvalidateRect(hWnd, NULL, TRUE); } break; case WM_PAINT: dprintf_msgbox(stddeb, "MessageBox WM_PAINT hWnd=%04X !\n", hWnd); lpmb = MsgBoxGetStorageHeader(hWnd); if (lpmb == NULL) break; if (!lpmb->ActiveFlg) break; hDC = BeginPaint(hWnd, &ps); if (hDC == 0) { printf("MessageBox WM_PAINT // BeginPaint returned BAD hDC !\n"); break; } GetClientRect(hWnd, &rect); FillRect(hDC, &rect, GetStockObject(WHITE_BRUSH)); CopyRect(&rect, &lpmb->rectStr); OldTextColor = SetTextColor(hDC, 0x00000000); if (lpmb->hIcon) DrawIcon(hDC, lpmb->rectIcon.left, lpmb->rectIcon.top, lpmb->hIcon); DrawText(hDC, lpmb->Str, -1, &rect, DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_WORDBREAK); rect.top = lpmb->rectStr.bottom / 2 - rect.bottom / 2; rect.bottom = lpmb->rectStr.bottom / 2 + rect.bottom / 2; DrawText(hDC, lpmb->Str, -1, &rect, DT_LEFT | DT_VCENTER | DT_WORDBREAK); SetTextColor(hDC, OldTextColor); EndPaint(hWnd, &ps); dprintf_msgbox(stddeb, "MessageBox End of WM_PAINT !\n"); break; case WM_DESTROY: dprintf_msgbox(stddeb, "MessageBox WM_DESTROY !\n"); ReleaseCapture(); lpmb = MsgBoxGetStorageHeader(hWnd); if (lpmb == NULL) break; if (lpmb->hIcon) DestroyIcon(lpmb->hIcon); if (lpmb->hWndYes) DestroyWindow(lpmb->hWndYes); if (lpmb->hWndNo) DestroyWindow(lpmb->hWndNo); if (lpmb->hWndCancel) DestroyWindow(lpmb->hWndCancel); dprintf_msgbox(stddeb, "MessageBox WM_DESTROY end !\n"); lpmb->ActiveFlg = FALSE; break; case WM_COMMAND: lpmb = MsgBoxGetStorageHeader(hWnd); if (lpmb == NULL) break; if (wParam < IDOK || wParam > IDNO) return(0); lpmb->wRetVal = wParam; dprintf_msgbox(stddeb, "MessageBox sending WM_CLOSE !\n"); PostMessage(hWnd, WM_CLOSE, 0, 0L); break; case WM_CHAR: lpmb = MsgBoxGetStorageHeader(hWnd); /* if (wParam >= 'a' || wParam <= 'z') wParam -= 'a' - 'A'; */ wParam = toupper(wParam); if (wParam == ButtonText.Yes.Hotkey) lpmb->wRetVal = IDYES; else if (wParam == ButtonText.Ok.Hotkey) lpmb->wRetVal = IDOK; else if (wParam == ButtonText.Retry.Hotkey) lpmb->wRetVal = IDRETRY; else if (wParam == ButtonText.Abort.Hotkey) lpmb->wRetVal = IDABORT; else if (wParam == ButtonText.No.Hotkey) lpmb->wRetVal = IDNO; else if (wParam == ButtonText.Ignore.Hotkey) lpmb->wRetVal = IDIGNORE; else if ((wParam == ButtonText.Ok.Hotkey) || (wParam == VK_ESCAPE)) lpmb->wRetVal = IDCANCEL; else return 0; if (lpmb == NULL) break; ShowWindow(hWnd, SW_HIDE); PostMessage(hWnd, WM_CLOSE, 0, 0L); break; default: return DefWindowProc(hWnd, message, wParam, lParam ); } return(0); } /************************************************************************* * "About Wine..." Dialog Box */ BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam) { HDC hDC; HDC hMemDC; PAINTSTRUCT ps; RECT rect; BITMAP bm; OFSTRUCT ofstruct; HBITMAP hbmpOld; static LPSTR ptr; static char str[256]; static HBITMAP hBitMap = 0; static BOOL CreditMode; static HANDLE hFile = 0; switch (msg) { case WM_INITDIALOG: CreditMode = FALSE; strcpy(str, "WINELOGO"); hBitMap = LoadBitmap((HINSTANCE)NULL, (LPSTR)str); strcpy(str, "LICENSE"); printf("str = '%s'\n", str); hFile = OpenFile((LPSTR)str, &ofstruct, OF_READ); ptr = (LPSTR)malloc(2048); lseek(hFile, 0L, SEEK_SET); _lread(hFile, ptr, 2000L); close(hFile); return TRUE; case WM_PAINT: hDC = BeginPaint(hDlg, &ps); GetClientRect(hDlg, &rect); if (CreditMode) { FillRect(hDC, &rect, GetStockObject(WHITE_BRUSH)); InflateRect(&rect, -8, -8); DrawText(hDC, ptr, -1, &rect, DT_LEFT | DT_WORDBREAK); EndPaint(hDlg, &ps); return TRUE; } FillRect(hDC, &rect, GetStockObject(GRAY_BRUSH)); InflateRect(&rect, -3, -3); FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); InflateRect(&rect, -10, -10); hMemDC = CreateCompatibleDC(hDC); hbmpOld = SelectObject(hMemDC, hBitMap); GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm); BitBlt(hDC, rect.left, rect.top, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); SelectObject( hMemDC, hbmpOld ); DeleteDC(hMemDC); EndPaint(hDlg, &ps); return TRUE; case WM_COMMAND: switch (wParam) { case IDYES: if (!CreditMode) { SetWindowPos(hDlg, (HWND)NULL, 0, 0, 640, 480, SWP_NOMOVE | SWP_NOZORDER); } else { SetWindowPos(hDlg, (HWND)NULL, 0, 0, 320, 250, SWP_NOMOVE | SWP_NOZORDER); } CreditMode = !CreditMode; ShowWindow(GetDlgItem(hDlg, IDYES), CreditMode ? SW_HIDE : SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDOK), CreditMode ? SW_HIDE : SW_SHOW); InvalidateRect(hDlg, (LPRECT)NULL, TRUE); UpdateWindow(hDlg); return TRUE; case IDCANCEL: case IDOK: if (hBitMap != 0 ) DeleteObject(hBitMap); if (ptr != NULL) free(ptr); EndDialog(hDlg, TRUE); return TRUE; default: return TRUE; } } return FALSE; } /************************************************************************** * FatalAppExit [USER.137] */ void FatalAppExit(WORD wAction, LPSTR str) { MessageBox((HWND)NULL, str, NULL, MB_SYSTEMMODAL | MB_OK); exit(1); }