1 /*
2  *  ReactOS Standard Dialog Application Template
3  *
4  *  memdlg.c
5  *
6  *  Copyright (C) 2002  Robert Dickenson <robd@reactos.org>
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 #define WIN32_LEAN_AND_MEAN
24 #include <windows.h>
25 #include <tchar.h>
26 #include "trace.h"
27 
28 
29 extern HINSTANCE hInst;
30 
31 #define ID_HELP   150
32 #define ID_TEXT   200
33 
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 LRESULT CALLBACK DialogWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
37 {
38     return 0;
39 }
40 
41 LPWORD lpwAlign(LPWORD lpIn)
42 {
43     ULONG_PTR ul;
44 
45     ul = (ULONG_PTR)lpIn;
46     ul += 3;
47     ul >>= 2;
48     ul <<= 2;
49     return (LPWORD)ul;
50 }
51 
52 ////////////////////////////////////////////////////////////////////////////////
53 // Create an in memory dialog resource and display.
54 //  Note: this doesn't work
55 //
56 LRESULT CreateMemoryDialog(HINSTANCE hinst, HWND hwndOwner, LPSTR lpszMessage)
57 {
58     HGLOBAL hgbl;
59     LPDLGTEMPLATE lpdt;
60     LPDLGITEMTEMPLATE lpdit;
61     LPWORD lpw;
62     LPWSTR lpwsz;
63     LRESULT ret;
64     int nchar;
65 
66     hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
67     if (!hgbl)
68         return -1;
69 
70     lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);
71 
72     // Define a dialog box.
73     lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION;
74     lpdt->cdit = 3;  // number of controls
75     lpdt->x  = 10; lpdt->y  = 10;
76     lpdt->cx = 100; lpdt->cy = 100;
77     lpw = (LPWORD)(lpdt + 1);
78     *lpw++ = 0;   // no menu
79     *lpw++ = 0;   // predefined dialog box class (by default)
80 
81     lpwsz = (LPWSTR)lpw;
82     nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "My Dialog", -1, lpwsz, 50);
83     lpw += nchar;
84 
85     //-----------------------
86     // Define an OK button.
87     //-----------------------
88     lpw = lpwAlign(lpw); // align DLGITEMTEMPLATE on DWORD boundary
89     lpdit = (LPDLGITEMTEMPLATE)lpw;
90     lpdit->x  = 10; lpdit->y  = 70;
91     lpdit->cx = 80; lpdit->cy = 20;
92     lpdit->id = IDOK;  // OK button identifier
93     lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
94 
95     lpw = (LPWORD)(lpdit + 1);
96     *lpw++ = 0xFFFF;
97     *lpw++ = 0x0080;    // button class
98 
99     lpwsz = (LPWSTR)lpw;
100     nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "OK", -1, lpwsz, 50);
101     lpw += nchar;
102     lpw = lpwAlign(lpw); // align creation data on DWORD boundary
103     *lpw++ = 0;           // no creation data
104 
105     //-----------------------
106     // Define a Help button.
107     //-----------------------
108     lpw = lpwAlign(lpw); // align DLGITEMTEMPLATE on DWORD boundary
109     lpdit = (LPDLGITEMTEMPLATE)lpw;
110     lpdit->x  = 55; lpdit->y  = 10;
111     lpdit->cx = 40; lpdit->cy = 20;
112     lpdit->id = ID_HELP;    // Help button identifier
113     lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;
114 
115     lpw = (LPWORD)(lpdit + 1);
116     *lpw++ = 0xFFFF;
117     *lpw++ = 0x0080;                 // button class atom
118 
119     lpwsz = (LPWSTR)lpw;
120     nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "Help", -1, lpwsz, 50);
121     lpw += nchar;
122     lpw = lpwAlign(lpw); // align creation data on DWORD boundary
123     *lpw++ = 0;           // no creation data
124 
125     //-----------------------
126     // Define a static text control.
127     //-----------------------
128     lpw = lpwAlign(lpw); // align DLGITEMTEMPLATE on DWORD boundary
129     lpdit = (LPDLGITEMTEMPLATE)lpw;
130     lpdit->x  = 10; lpdit->y  = 10;
131     lpdit->cx = 40; lpdit->cy = 20;
132     lpdit->id = ID_TEXT;  // text identifier
133     lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;
134 
135     lpw = (LPWORD)(lpdit + 1);
136     *lpw++ = 0xFFFF;
137     *lpw++ = 0x0082;                         // static class
138 
139     for (lpwsz = (LPWSTR)lpw;
140         *lpwsz++ == (WCHAR)*lpszMessage++;
141     );
142     lpw = (LPWORD)lpwsz;
143     lpw = lpwAlign(lpw);  // align creation data on DWORD boundary
144     *lpw++ = 0;           // no creation data
145 
146     GlobalUnlock(hgbl);
147     ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE)hgbl, hwndOwner, (DLGPROC)DialogWndProc);
148     if (ret == 0) {
149         TRACE(_T("DialogBoxIndirect() failed due to invalid handle to parent window: 0x%08X"), hwndOwner);
150     } else if (ret == -1) {
151         DWORD error = GetLastError();
152         TRACE(_T("DialogBoxIndirect() failed, GetLastError returned 0x%08X"), error);
153     }
154     GlobalFree(hgbl);
155     return ret;
156 }
157 
158 ////////////////////////////////////////////////////////////////////////////////
159