/**************************************************************************\ * Simple sample to show how to dynamically create Win32 dialogs. * * Steve Firebaugh * Microsoft Developer Support * Copyright (c) 1992 Microsoft Corporation * * * Post questions or folloups to Compuserve MSWIN32, section 4, * attn: Steve Firebaugh * * For more information on the resource formats in Win32 look for the * RESFMT.ZIP file. * \**************************************************************************/ #define UNICODE #include LRESULT APIENTRY MainWndProc(HWND, UINT, UINT, LONG); LRESULT APIENTRY About(HWND, UINT, WPARAM, LPARAM ); /**************************************************************************\ * * function: WinMain() * * input parameters: c.f. generic sample * \**************************************************************************/ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hwnd; MSG msg; UNREFERENCED_PARAMETER( lpCmdLine ); /* Check for previous instance. If none, then register class. */ if (!hPrevInstance) { WNDCLASS wc; wc.style = NULL; wc.lpfnWndProc = (WNDPROC)MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(LTGRAY_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = TEXT("base"); if (!RegisterClass(&wc)) return (FALSE); } /* class registered o.k. */ /* Create the main window. Return false if CreateWindow() fails */ hwnd = CreateWindow( TEXT("base"), TEXT("base"), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if (!hwnd) return (FALSE); /*+++ Create the first dialog dynamically. Notice that we are NOT using structures here because too many of the fields are of variable length. Instead, just allocate some memory to play with, and start filling in the data at that pointer. p - pointer which is moved down through the DLGTEMPLATE information. pdlgtemplate - pointer to the TOP of the DLGTEMPLATE information. Notice that UNICODE is defined to be on in this module. That means: 1. All strings included in TEXT() macro will be made unicode strings by the compiler. 2. wsprintf() will accept a unicode string as input, and will fill its lpOut buffer with a unicode string. Notice that in any case, the return value is the number of *characters* not the number of bytes. 3. Any system call which may be dependent upon unicode will be mapped to its wide character version (*W not *A) by the header files. Howard Myers has pointed out that this does not matter for the CreateDialogIndirect() call. Both the A and W versions expect the dialog template to contain wide character strings. Here we create a simple dialog with one item. The dialog has a title, the item has text, and the item class is specified by ordinal. There is no font information. ---*/ { WORD *p, *pdlgtemplate; int nchar; /* declare variables purely for ease of reading the names provide. */ DWORD lStyle; DWORD lExtendedStyle; WORD NumberOfItems; WORD x; WORD y; WORD cx; WORD cy; WORD wId; /* allocate some memory to play with */ pdlgtemplate = p = (PWORD) LocalAlloc (LPTR, 1000); lStyle = DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | WS_VISIBLE; lExtendedStyle = 0; NumberOfItems = 1; x = 10; y = 10; cx = 100; cy = 100; /* start to fill in the dlgtemplate information. addressing by WORDs */ *p++ = LOWORD (lStyle); *p++ = HIWORD (lStyle); *p++ = LOWORD (lExtendedStyle); *p++ = HIWORD (lExtendedStyle); *p++ = NumberOfItems; *p++ = x ; *p++ = y ; *p++ = cx; *p++ = cy; *p++ = 0; // Menu *p++ = 0; // Class /* copy the title of the dialog, null terminate the string. */ nchar = wsprintf (p, TEXT("Title 1")); p += nchar; *p++ = 0; /* add in the wPointSize and szFontName here iff the DS_SETFONT bit on */ /* make sure the first item starts on a DWORD boundary */ { ULONG l; l = (ULONG) p; l +=3; l >>=2; l <<=2; p = (PWORD) l; } /* now start with the first item */ lStyle = BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD; x = 10; y = 70; cx = 80; cy = 10; wId = IDOK; *p++ = LOWORD (lStyle); *p++ = HIWORD (lStyle); *p++ = LOWORD (lExtendedStyle); *p++ = HIWORD (lExtendedStyle); *p++ = x ; *p++ = y ; *p++ = cx; *p++ = cy; *p++ = wId; /* fill in class i.d. Button in this case */ *p++ = (WORD)0xffff; *p++ = (WORD)0x0080; /* copy the text of the first item, null terminate the string. */ nchar = wsprintf (p, TEXT("OK")); p += nchar; *p++ = 0; CreateDialogIndirect (hInstance, (LPDLGTEMPLATE) pdlgtemplate, hwnd, (DLGPROC) About); LocalFree (LocalHandle (pdlgtemplate)); } /*+++ Create the second dialog dynamically. Here we create a dialog which has font information (DS_SETFONT), and which has two items with the item class specified by name. BUG BUG. Notice that there is an outstanding, peculiar bug in the October beta release which affects dialogs that set their font. When the application is run for the second time, the font information is screwed up, and the edit fields do not work correctly. ????? This is a known bug, and a fix is in progress for the next release. ---*/ { WORD *p, *pdlgtemplate; int nchar; /* declare variables purely for ease of reading the names provide. */ DWORD lStyle; DWORD lExtendedStyle; WORD NumberOfItems; WORD x; WORD y; WORD cx; WORD cy; WORD wId; /* allocate some memory to play with */ pdlgtemplate = p = (PWORD) LocalAlloc (LPTR, 1000); lStyle = DS_SETFONT | WS_CAPTION | WS_SYSMENU | WS_VISIBLE; lExtendedStyle = 0; NumberOfItems = 2; x = 210; y = 10; cx = 100; cy = 100; /* start to fill in the dlgtemplate information. addressing by WORDs */ *p++ = LOWORD (lStyle); *p++ = HIWORD (lStyle); *p++ = LOWORD (lExtendedStyle); *p++ = HIWORD (lExtendedStyle); *p++ = NumberOfItems; *p++ = x ; *p++ = y ; *p++ = cx; *p++ = cy; *p++ = 0; // Menu *p++ = 0; // Class /* copy the title of the dialog, null terminate the string. */ nchar = wsprintf (p, TEXT("Title 2")); p += nchar; *p++ = 0; /* add in the wPointSize and szFontName here iff the DS_SETFONT bit on */ *p++ = 24; nchar = wsprintf (p, TEXT("Courier")); p += nchar; *p++ = 0; /* make sure the first item starts on a DWORD boundary */ { ULONG l; l = (ULONG) p; l +=3; l >>=2; l <<=2; p = (PWORD) l; } /* now start with the first item */ lStyle = BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP; x = 10; y = 60; cx = 80; cy = 20; wId = IDOK; *p++ = LOWORD (lStyle); *p++ = HIWORD (lStyle); *p++ = LOWORD (lExtendedStyle); *p++ = HIWORD (lExtendedStyle); *p++ = x ; *p++ = y ; *p++ = cx; *p++ = cy; *p++ = wId; /* fill in class i.d., this time by name */ nchar = wsprintf (p, TEXT("BUTTON")); p += nchar; *p++ = 0; /* copy the text of the first item, null terminate the string. */ nchar = wsprintf (p, TEXT("OK")); p += nchar; *p++ = 0; /* make sure the second item starts on a DWORD boundary */ { ULONG l; l = (ULONG) p; l +=3; l >>=2; l <<=2; p = (PWORD) l; } lStyle = ES_CENTER | ES_MULTILINE | WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP; x = 10; y = 20; cx = 80; cy = 20; wId = 57; *p++ = LOWORD (lStyle); *p++ = HIWORD (lStyle); *p++ = LOWORD (lExtendedStyle); *p++ = HIWORD (lExtendedStyle); *p++ = x ; *p++ = y ; *p++ = cx; *p++ = cy; *p++ = wId; /* fill in class i.d., this time by name */ nchar = wsprintf (p, TEXT("EDIT")); p += nchar; *p++ = 0; /* copy the text of the second item, null terminate the string. */ nchar = wsprintf (p, TEXT("Edit string")); p += nchar; *p++ = 0; CreateDialogIndirect (hInstance, (LPDLGTEMPLATE) pdlgtemplate, hwnd, (DLGPROC) About); LocalFree (LocalHandle (pdlgtemplate)); } /* Loop getting messages and dispatching them. */ while (GetMessage(&msg,NULL, NULL, NULL)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (msg.wParam); } /***************************************************************************\ * FUNCTION: MainWndProc \***************************************************************************/ LRESULT APIENTRY MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_PAINT: { HDC hdc; PAINTSTRUCT ps; hdc = BeginPaint(hwnd, &ps); EndPaint (hwnd, &ps); } return FALSE; case WM_DESTROY: PostQuitMessage(0); break; default: break; } /* end switch */ return (DefWindowProc(hwnd, message, wParam, lParam)); } /***************************************************************************\ * FUNCTION: About \***************************************************************************/ LRESULT APIENTRY About(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if ((message == WM_COMMAND) && (LOWORD(wParam) == IDOK)) { EndDialog (hwnd, TRUE); return TRUE; } if ((message == WM_SYSCOMMAND) && (wParam == SC_CLOSE)) { EndDialog (hwnd, TRUE); return TRUE; } return FALSE; }