xref: /reactos/base/shell/progman/main.c (revision 1a102501)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Program Manager
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 1996 Ulrich Schmid
5c2c66affSColin Finck  * Copyright 2002 Sylvain Petreolle
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck  *
12c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15c2c66affSColin Finck  * Lesser General Public License for more details.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck  */
21c2c66affSColin Finck 
22c2c66affSColin Finck /*
23c2c66affSColin Finck  * PROJECT:         ReactOS Program Manager
24c2c66affSColin Finck  * COPYRIGHT:       GPL - See COPYING in the top level directory
25c2c66affSColin Finck  * FILE:            base/shell/progman/main.c
26c2c66affSColin Finck  * PURPOSE:         ProgMan entry point & MDI window
27c2c66affSColin Finck  * PROGRAMMERS:     Ulrich Schmid
28c2c66affSColin Finck  *                  Sylvain Petreolle
29c2c66affSColin Finck  *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
30c2c66affSColin Finck  */
31c2c66affSColin Finck 
32c2c66affSColin Finck #include "progman.h"
33c2c66affSColin Finck 
34c2c66affSColin Finck #include <shellapi.h>
35c2c66affSColin Finck 
36c2c66affSColin Finck #define WC_MDICLIENTA        "MDICLIENT"
37c2c66affSColin Finck #define WC_MDICLIENTW       L"MDICLIENT"
38c2c66affSColin Finck 
39c2c66affSColin Finck #ifdef UNICODE
40c2c66affSColin Finck #define WC_MDICLIENT        WC_MDICLIENTW
41c2c66affSColin Finck #else
42c2c66affSColin Finck #define WC_MDICLIENT        WC_MDICLIENTA
43c2c66affSColin Finck #endif
44c2c66affSColin Finck 
45c2c66affSColin Finck GLOBALS Globals;
46c2c66affSColin Finck 
47c2c66affSColin Finck static VOID MAIN_LoadGroups(VOID);
48c2c66affSColin Finck static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
49c2c66affSColin Finck static ATOM MAIN_RegisterMainWinClass(VOID);
50c2c66affSColin Finck static VOID MAIN_CreateMainWindow(VOID);
51c2c66affSColin Finck static VOID MAIN_CreateMDIWindow(VOID);
52c2c66affSColin Finck static VOID MAIN_AutoStart(VOID);
53c2c66affSColin Finck 
54c2c66affSColin Finck 
55c2c66affSColin Finck #define BUFFER_SIZE 1024
56c2c66affSColin Finck 
57c2c66affSColin Finck 
58c2c66affSColin Finck 
59c2c66affSColin Finck /*
60c2c66affSColin Finck  * Memory management functions
61c2c66affSColin Finck  */
62c2c66affSColin Finck PVOID
Alloc(IN DWORD dwFlags,IN SIZE_T dwBytes)63c2c66affSColin Finck Alloc(IN DWORD  dwFlags,
64c2c66affSColin Finck       IN SIZE_T dwBytes)
65c2c66affSColin Finck {
66c2c66affSColin Finck     return HeapAlloc(GetProcessHeap(), dwFlags, dwBytes);
67c2c66affSColin Finck }
68c2c66affSColin Finck 
69c2c66affSColin Finck BOOL
Free(IN PVOID lpMem)70c2c66affSColin Finck Free(IN PVOID lpMem)
71c2c66affSColin Finck {
72c2c66affSColin Finck     return HeapFree(GetProcessHeap(), 0, lpMem);
73c2c66affSColin Finck }
74c2c66affSColin Finck 
75c2c66affSColin Finck PVOID
ReAlloc(IN DWORD dwFlags,IN PVOID lpMem,IN SIZE_T dwBytes)76c2c66affSColin Finck ReAlloc(IN DWORD  dwFlags,
77c2c66affSColin Finck         IN PVOID  lpMem,
78c2c66affSColin Finck         IN SIZE_T dwBytes)
79c2c66affSColin Finck {
80c2c66affSColin Finck     return HeapReAlloc(GetProcessHeap(), dwFlags, lpMem, dwBytes);
81c2c66affSColin Finck }
82c2c66affSColin Finck 
83c2c66affSColin Finck PVOID
AppendToBuffer(IN PVOID pBuffer,IN PSIZE_T pdwBufferSize,IN PVOID pData,IN SIZE_T dwDataSize)84c2c66affSColin Finck AppendToBuffer(IN PVOID   pBuffer,
85c2c66affSColin Finck                IN PSIZE_T pdwBufferSize,
86c2c66affSColin Finck                IN PVOID   pData,
87c2c66affSColin Finck                IN SIZE_T  dwDataSize)
88c2c66affSColin Finck {
89c2c66affSColin Finck     PVOID  pTmp;
90c2c66affSColin Finck     SIZE_T dwBufferSize;
91c2c66affSColin Finck 
92c2c66affSColin Finck     dwBufferSize = dwDataSize + *pdwBufferSize;
93c2c66affSColin Finck 
94c2c66affSColin Finck     if (pBuffer)
95c2c66affSColin Finck         pTmp = ReAlloc(0, pBuffer, dwBufferSize);
96c2c66affSColin Finck     else
97c2c66affSColin Finck         pTmp = Alloc(0, dwBufferSize);
98c2c66affSColin Finck 
99c2c66affSColin Finck     if (!pTmp)
100c2c66affSColin Finck         return NULL;
101c2c66affSColin Finck 
102c2c66affSColin Finck     memcpy((PVOID)((ULONG_PTR)pTmp + *pdwBufferSize), pData, dwDataSize);
103c2c66affSColin Finck     *pdwBufferSize = dwBufferSize;
104c2c66affSColin Finck 
105c2c66affSColin Finck     return pTmp;
106c2c66affSColin Finck }
107c2c66affSColin Finck 
108c2c66affSColin Finck 
109c2c66affSColin Finck 
110c2c66affSColin Finck /*
111c2c66affSColin Finck  * Debugging helpers
112c2c66affSColin Finck  */
113c2c66affSColin Finck VOID
PrintStringV(IN LPCWSTR szStr,IN va_list args)114c2c66affSColin Finck PrintStringV(IN LPCWSTR szStr,
115c2c66affSColin Finck              IN va_list args)
116c2c66affSColin Finck {
117c2c66affSColin Finck     WCHAR Buffer[4096];
118c2c66affSColin Finck 
119c2c66affSColin Finck     _vsnwprintf(Buffer, ARRAYSIZE(Buffer), szStr, args);
120c2c66affSColin Finck     MessageBoxW(Globals.hMainWnd, Buffer, L"Information", MB_OK);
121c2c66affSColin Finck }
122c2c66affSColin Finck 
123c2c66affSColin Finck VOID
PrintString(IN LPCWSTR szStr,...)124c2c66affSColin Finck PrintString(IN LPCWSTR szStr, ...)
125c2c66affSColin Finck {
126c2c66affSColin Finck     va_list args;
127c2c66affSColin Finck 
128c2c66affSColin Finck     va_start(args, szStr);
129c2c66affSColin Finck     PrintStringV(szStr, args);
130c2c66affSColin Finck     va_end(args);
131c2c66affSColin Finck }
132c2c66affSColin Finck 
133c2c66affSColin Finck VOID
PrintResourceString(IN UINT uID,...)134c2c66affSColin Finck PrintResourceString(IN UINT uID, ...)
135c2c66affSColin Finck {
136c2c66affSColin Finck     WCHAR Buffer[4096];
137c2c66affSColin Finck     va_list args;
138c2c66affSColin Finck 
139c2c66affSColin Finck     va_start(args, uID);
140c2c66affSColin Finck     LoadStringW(Globals.hInstance, uID, Buffer, ARRAYSIZE(Buffer));
141c2c66affSColin Finck     PrintStringV(Buffer, args);
142c2c66affSColin Finck     va_end(args);
143c2c66affSColin Finck }
144c2c66affSColin Finck 
145c2c66affSColin Finck VOID
PrintWin32Error(IN LPWSTR Message,IN DWORD ErrorCode)146c2c66affSColin Finck PrintWin32Error(IN LPWSTR Message, IN DWORD ErrorCode)
147c2c66affSColin Finck {
148c2c66affSColin Finck     LPWSTR lpMsgBuf;
149c2c66affSColin Finck 
150c2c66affSColin Finck     FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
151c2c66affSColin Finck                    NULL, ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
152c2c66affSColin Finck                    (LPWSTR)&lpMsgBuf, 0, NULL);
153c2c66affSColin Finck 
154c2c66affSColin Finck     PrintString(L"%s: %s\n", Message, lpMsgBuf);
155c2c66affSColin Finck     LocalFree(lpMsgBuf);
156c2c66affSColin Finck }
157c2c66affSColin Finck 
ShowLastWin32Error(VOID)158c2c66affSColin Finck int ShowLastWin32Error(VOID)
159c2c66affSColin Finck {
160c2c66affSColin Finck     DWORD dwError;
161c2c66affSColin Finck     LPWSTR lpMsgBuf = NULL;
162c2c66affSColin Finck     WCHAR Buffer[4096];
163c2c66affSColin Finck 
164c2c66affSColin Finck     dwError = GetLastError();
165c2c66affSColin Finck 
166c2c66affSColin Finck     FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
167c2c66affSColin Finck                    NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
168c2c66affSColin Finck                    (LPWSTR)&lpMsgBuf, 0, NULL);
169c2c66affSColin Finck     _snwprintf(Buffer, ARRAYSIZE(Buffer), L"Error %d: %s\n", dwError, lpMsgBuf);
170c2c66affSColin Finck     LocalFree(lpMsgBuf);
171c2c66affSColin Finck     return MessageBoxW(Globals.hMainWnd, Buffer, L"Error", MB_OK);
172c2c66affSColin Finck }
173c2c66affSColin Finck 
174c2c66affSColin Finck 
175c2c66affSColin Finck 
176c2c66affSColin Finck 
177c2c66affSColin Finck 
178c2c66affSColin Finck 
179c2c66affSColin Finck 
180c2c66affSColin Finck /* Copied and adapted from dll/win32/userenv/environment.c!GetUserAndDomainName */
181c2c66affSColin Finck static
182c2c66affSColin Finck BOOL
GetUserAndDomainName(OUT LPWSTR * UserName,OUT LPWSTR * DomainName)183c2c66affSColin Finck GetUserAndDomainName(OUT LPWSTR* UserName,
184c2c66affSColin Finck                      OUT LPWSTR* DomainName)
185c2c66affSColin Finck {
186c2c66affSColin Finck     BOOL bRet = TRUE;
187c2c66affSColin Finck     HANDLE hToken;
188c2c66affSColin Finck     DWORD cbTokenBuffer = 0;
189c2c66affSColin Finck     PTOKEN_USER pUserToken;
190c2c66affSColin Finck 
191c2c66affSColin Finck     LPWSTR lpUserName   = NULL;
192c2c66affSColin Finck     LPWSTR lpDomainName = NULL;
193c2c66affSColin Finck     DWORD  cbUserName   = 0;
194c2c66affSColin Finck     DWORD  cbDomainName = 0;
195c2c66affSColin Finck 
196c2c66affSColin Finck     SID_NAME_USE SidNameUse;
197c2c66affSColin Finck 
198c2c66affSColin Finck     /* Get the process token */
199c2c66affSColin Finck     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
200c2c66affSColin Finck         return FALSE;
201c2c66affSColin Finck 
202c2c66affSColin Finck     /* Retrieve token's information */
203c2c66affSColin Finck     if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &cbTokenBuffer))
204c2c66affSColin Finck     {
205c2c66affSColin Finck         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
206c2c66affSColin Finck         {
207c2c66affSColin Finck             CloseHandle(hToken);
208c2c66affSColin Finck             return FALSE;
209c2c66affSColin Finck         }
210c2c66affSColin Finck     }
211c2c66affSColin Finck 
212c2c66affSColin Finck     pUserToken = Alloc(HEAP_ZERO_MEMORY, cbTokenBuffer);
213c2c66affSColin Finck     if (!pUserToken)
214c2c66affSColin Finck     {
215c2c66affSColin Finck         CloseHandle(hToken);
216c2c66affSColin Finck         return FALSE;
217c2c66affSColin Finck     }
218c2c66affSColin Finck 
219c2c66affSColin Finck     if (!GetTokenInformation(hToken, TokenUser, pUserToken, cbTokenBuffer, &cbTokenBuffer))
220c2c66affSColin Finck     {
221c2c66affSColin Finck         Free(pUserToken);
222c2c66affSColin Finck         CloseHandle(hToken);
223c2c66affSColin Finck         return FALSE;
224c2c66affSColin Finck     }
225c2c66affSColin Finck 
226c2c66affSColin Finck     CloseHandle(hToken);
227c2c66affSColin Finck 
228c2c66affSColin Finck     /* Retrieve the domain and user name */
229c2c66affSColin Finck     if (!LookupAccountSidW(NULL,
230c2c66affSColin Finck                            pUserToken->User.Sid,
231c2c66affSColin Finck                            NULL,
232c2c66affSColin Finck                            &cbUserName,
233c2c66affSColin Finck                            NULL,
234c2c66affSColin Finck                            &cbDomainName,
235c2c66affSColin Finck                            &SidNameUse))
236c2c66affSColin Finck     {
237c2c66affSColin Finck         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
238c2c66affSColin Finck         {
239c2c66affSColin Finck             bRet = FALSE;
240c2c66affSColin Finck             goto done;
241c2c66affSColin Finck         }
242c2c66affSColin Finck     }
243c2c66affSColin Finck 
244c2c66affSColin Finck     lpUserName = Alloc(HEAP_ZERO_MEMORY, cbUserName * sizeof(WCHAR));
245c2c66affSColin Finck     if (lpUserName == NULL)
246c2c66affSColin Finck     {
247c2c66affSColin Finck         bRet = FALSE;
248c2c66affSColin Finck         goto done;
249c2c66affSColin Finck     }
250c2c66affSColin Finck 
251c2c66affSColin Finck     lpDomainName = Alloc(HEAP_ZERO_MEMORY, cbDomainName * sizeof(WCHAR));
252c2c66affSColin Finck     if (lpDomainName == NULL)
253c2c66affSColin Finck     {
254c2c66affSColin Finck         bRet = FALSE;
255c2c66affSColin Finck         goto done;
256c2c66affSColin Finck     }
257c2c66affSColin Finck 
258c2c66affSColin Finck     if (!LookupAccountSidW(NULL,
259c2c66affSColin Finck                            pUserToken->User.Sid,
260c2c66affSColin Finck                            lpUserName,
261c2c66affSColin Finck                            &cbUserName,
262c2c66affSColin Finck                            lpDomainName,
263c2c66affSColin Finck                            &cbDomainName,
264c2c66affSColin Finck                            &SidNameUse))
265c2c66affSColin Finck     {
266c2c66affSColin Finck         bRet = FALSE;
267c2c66affSColin Finck         goto done;
268c2c66affSColin Finck     }
269c2c66affSColin Finck 
270c2c66affSColin Finck     *UserName   = lpUserName;
271c2c66affSColin Finck     *DomainName = lpDomainName;
272c2c66affSColin Finck 
273c2c66affSColin Finck done:
274c2c66affSColin Finck     if (bRet == FALSE)
275c2c66affSColin Finck     {
276c2c66affSColin Finck         if (lpUserName != NULL)
277c2c66affSColin Finck             Free(lpUserName);
278c2c66affSColin Finck 
279c2c66affSColin Finck         if (lpDomainName != NULL)
280c2c66affSColin Finck             Free(lpDomainName);
281c2c66affSColin Finck     }
282c2c66affSColin Finck 
283c2c66affSColin Finck     Free(pUserToken);
284c2c66affSColin Finck 
285c2c66affSColin Finck     return bRet;
286c2c66affSColin Finck }
287c2c66affSColin Finck 
288c2c66affSColin Finck 
289c2c66affSColin Finck 
290c2c66affSColin Finck 
291c2c66affSColin Finck 
292c2c66affSColin Finck 
293c2c66affSColin Finck static
294c2c66affSColin Finck VOID
MAIN_SetMainWindowTitle(VOID)295c2c66affSColin Finck MAIN_SetMainWindowTitle(VOID)
296c2c66affSColin Finck {
297c2c66affSColin Finck     LPWSTR caption;
298c2c66affSColin Finck     SIZE_T size;
299c2c66affSColin Finck 
300c2c66affSColin Finck     LPWSTR lpDomainName = NULL;
301c2c66affSColin Finck     LPWSTR lpUserName   = NULL;
302c2c66affSColin Finck 
303c2c66affSColin Finck     if (GetUserAndDomainName(&lpUserName, &lpDomainName) && lpUserName && lpDomainName)
304c2c66affSColin Finck     {
305c2c66affSColin Finck         size = (256 + 3 + wcslen(lpDomainName) + wcslen(lpUserName) + 1) * sizeof(WCHAR);
306c2c66affSColin Finck         caption = Alloc(HEAP_ZERO_MEMORY, size);
307c2c66affSColin Finck         if (caption)
308c2c66affSColin Finck         {
309c2c66affSColin Finck             StringCbPrintfW(caption, size, L"%s - %s\\%s", szTitle, lpDomainName, lpUserName);
310c2c66affSColin Finck             SetWindowTextW(Globals.hMainWnd, caption);
311c2c66affSColin Finck             Free(caption);
312c2c66affSColin Finck         }
313c2c66affSColin Finck         else
314c2c66affSColin Finck         {
315c2c66affSColin Finck             SetWindowTextW(Globals.hMainWnd, szTitle);
316c2c66affSColin Finck         }
317c2c66affSColin Finck     }
318c2c66affSColin Finck     else
319c2c66affSColin Finck     {
320c2c66affSColin Finck         SetWindowTextW(Globals.hMainWnd, szTitle);
321c2c66affSColin Finck     }
322c2c66affSColin Finck 
323c2c66affSColin Finck     if (lpUserName)   Free(lpUserName);
324c2c66affSColin Finck     if (lpDomainName) Free(lpDomainName);
325c2c66affSColin Finck }
326c2c66affSColin Finck 
327c2c66affSColin Finck 
328c2c66affSColin Finck 
329c2c66affSColin Finck 
330c2c66affSColin Finck static
331c2c66affSColin Finck BOOL
MAIN_LoadSettings(VOID)332c2c66affSColin Finck MAIN_LoadSettings(VOID)
333c2c66affSColin Finck {
334c2c66affSColin Finck     LPWSTR lpszTmp;
335c2c66affSColin Finck     LPWSTR lpszSection;
336c2c66affSColin Finck     LONG lRet;
337c2c66affSColin Finck     WCHAR dummy[2];
338c2c66affSColin Finck     LPWSTR lpszKeyValue;
339c2c66affSColin Finck     const LPCWSTR lpszIniFile = L"progman.ini";
340c2c66affSColin Finck     WCHAR szWinDir[MAX_PATH];
341c2c66affSColin Finck     LPWSTR lpszKey;
342c2c66affSColin Finck     DWORD Value;
343c2c66affSColin Finck     HKEY hKey;
344c2c66affSColin Finck     BOOL bIsIniMigrated;
345c2c66affSColin Finck     DWORD dwSize;
346c2c66affSColin Finck     LPWSTR lpszSections;
347c2c66affSColin Finck     LPWSTR lpszData;
348c2c66affSColin Finck     DWORD dwRet;
349c2c66affSColin Finck     DWORD dwType;
350c2c66affSColin Finck     LPWSTR lpszValue;
351c2c66affSColin Finck 
352c2c66affSColin Finck     bIsIniMigrated = FALSE;
353c2c66affSColin Finck     lpszSections = NULL;
354c2c66affSColin Finck     lpszData = NULL;
355c2c66affSColin Finck 
356c2c66affSColin Finck     /* Try to create/open the Program Manager user key */
357c2c66affSColin Finck     if (RegCreateKeyExW(HKEY_CURRENT_USER,
358c2c66affSColin Finck                         L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Program Manager",
359c2c66affSColin Finck                         0,
360c2c66affSColin Finck                         NULL,
361c2c66affSColin Finck                         REG_OPTION_NON_VOLATILE,
362c2c66affSColin Finck                         KEY_READ | KEY_WRITE,
363c2c66affSColin Finck                         NULL,
364c2c66affSColin Finck                         &Globals.hKeyProgMan,
365c2c66affSColin Finck                         NULL) != ERROR_SUCCESS)
366c2c66affSColin Finck     {
367c2c66affSColin Finck         return FALSE;
368c2c66affSColin Finck     }
369c2c66affSColin Finck 
370c2c66affSColin Finck     /*
371c2c66affSColin Finck      * TODO: Add the explanation for the migration...
372c2c66affSColin Finck      */
373c2c66affSColin Finck     dwSize = sizeof(Value);
374c2c66affSColin Finck     lRet = RegQueryValueExW(Globals.hKeyProgMan, L"IniMigrated", NULL, &dwType, (LPBYTE)&Value, &dwSize);
375c2c66affSColin Finck     if (lRet != ERROR_SUCCESS || dwType != REG_DWORD)
376c2c66affSColin Finck         Value = 0;
377c2c66affSColin Finck     bIsIniMigrated = !!Value;
378c2c66affSColin Finck 
379c2c66affSColin Finck     if (bIsIniMigrated)
380c2c66affSColin Finck     {
381c2c66affSColin Finck         /* The migration was already done, just load the settings */
382c2c66affSColin Finck         goto LoadSettings;
383c2c66affSColin Finck     }
384c2c66affSColin Finck 
385c2c66affSColin Finck     /* Perform the migration */
386c2c66affSColin Finck 
387c2c66affSColin Finck     bIsIniMigrated = TRUE;
388c2c66affSColin Finck     dwSize = ARRAYSIZE(dummy);
389c2c66affSColin Finck     SetLastError(0);
390c2c66affSColin Finck     GetPrivateProfileSectionW(L"Settings", dummy, dwSize, lpszIniFile);
391c2c66affSColin Finck     if (GetLastError() == ERROR_FILE_NOT_FOUND)
392c2c66affSColin Finck         goto MigrationDone;
393c2c66affSColin Finck 
394c2c66affSColin Finck     SetLastError(0);
395c2c66affSColin Finck     GetPrivateProfileSectionW(L"Groups", dummy, dwSize, lpszIniFile);
396c2c66affSColin Finck     if (GetLastError() == ERROR_FILE_NOT_FOUND)
397c2c66affSColin Finck         goto MigrationDone;
398c2c66affSColin Finck 
399c2c66affSColin Finck     GetWindowsDirectoryW(szWinDir, ARRAYSIZE(szWinDir));
400c2c66affSColin Finck     // NOTE: GCC complains we cannot use the "\u2022" (UNICODE Code Point) notation for specifying the bullet character,
401c2c66affSColin Finck     // because it's only available in C++ or in C99. On the contrary MSVC is fine with it.
402c2c66affSColin Finck     // Instead we use a hex specification for the character: "\x2022".
403c2c66affSColin Finck     // Note also that the character "\x07" gives also a bullet, but a larger one.
404c2c66affSColin Finck     PrintString(
405c2c66affSColin Finck         L"The Program Manager has detected the presence of a legacy settings file PROGMAN.INI in the directory '%s' "
406c2c66affSColin Finck         L"and is going to migrate its contents into the current-user Program Manager settings registry key:\n"
407c2c66affSColin Finck         L"HKCU\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Program Manager"
408c2c66affSColin Finck         L"\n\n"
409c2c66affSColin Finck         L"\x2022 The migration operation will potentially overwrite all the existing current-user Program Manager settings in the registry by those stored in the PROGMAN.INI file.\n"
410c2c66affSColin Finck         L"\n"
411c2c66affSColin Finck         L"\x2022 The migration is done once, so that, at the next launch of the Program Manager, the new migrated settings are directly used.\n"
412c2c66affSColin Finck         L"\n"
413c2c66affSColin Finck         L"\x2022 It is possible to trigger later the migration by manually deleting the registry value \"IniMigrated\" under the current-user Program Manager settings registry key (specified above).\n"
414c2c66affSColin Finck         L"\n"
415c2c66affSColin Finck         L"Would you like to migrate its contents into the registry?",
416c2c66affSColin Finck         szWinDir);
417c2c66affSColin Finck 
418c2c66affSColin Finck     for (dwSize = BUFFER_SIZE; ; dwSize += BUFFER_SIZE)
419c2c66affSColin Finck     {
420c2c66affSColin Finck         lpszSections = Alloc(0, dwSize * sizeof(WCHAR));
421c2c66affSColin Finck         dwRet = GetPrivateProfileSectionNamesW(lpszSections, dwSize, lpszIniFile);
422c2c66affSColin Finck         if (dwRet < dwSize - 2)
423c2c66affSColin Finck             break;
424c2c66affSColin Finck         Free(lpszSections);
425c2c66affSColin Finck     }
426c2c66affSColin Finck     lpszSection = lpszSections;
427c2c66affSColin Finck     while (*lpszSection)
428c2c66affSColin Finck     {
429c2c66affSColin Finck         lRet = RegCreateKeyExW(Globals.hKeyProgMan,
430c2c66affSColin Finck                                 lpszSection,
431c2c66affSColin Finck                                 0,
432c2c66affSColin Finck                                 NULL,
433c2c66affSColin Finck                                 REG_OPTION_NON_VOLATILE,
434c2c66affSColin Finck                                 KEY_WRITE,
435c2c66affSColin Finck                                 NULL,
436c2c66affSColin Finck                                 &hKey,
437c2c66affSColin Finck                                 NULL);
438c2c66affSColin Finck         if (lRet == ERROR_SUCCESS)
439c2c66affSColin Finck         {
440c2c66affSColin Finck             for (dwSize = BUFFER_SIZE; ; dwSize += BUFFER_SIZE)
441c2c66affSColin Finck             {
442c2c66affSColin Finck                 lpszData = Alloc(0, dwSize * sizeof(WCHAR));
443c2c66affSColin Finck                 dwRet = GetPrivateProfileSectionW(lpszSection, lpszData, dwSize, lpszIniFile);
444c2c66affSColin Finck                 if (dwRet < dwSize - 2)
445c2c66affSColin Finck                     break;
446c2c66affSColin Finck                 Free(lpszData);
447c2c66affSColin Finck             }
448c2c66affSColin Finck             lpszKeyValue = lpszData;
449c2c66affSColin Finck             while (*lpszKeyValue)
450c2c66affSColin Finck             {
451c2c66affSColin Finck                 lpszKey = lpszKeyValue;
452c2c66affSColin Finck                 lpszValue = wcschr(lpszKeyValue, L'=');
453c2c66affSColin Finck                 lpszKeyValue += (wcslen(lpszKeyValue) + 1);
454c2c66affSColin Finck                 if (lpszValue)
455c2c66affSColin Finck                 {
456c2c66affSColin Finck                     *lpszValue = '\0';
457c2c66affSColin Finck                     ++lpszValue;
458c2c66affSColin Finck                     Value = wcstoul(lpszValue, &lpszTmp, 0);
459c2c66affSColin Finck                     if (lpszTmp - lpszValue >= wcslen(lpszValue))
460c2c66affSColin Finck                     {
461c2c66affSColin Finck                         lpszValue = (LPWSTR)&Value;
462c2c66affSColin Finck                         dwSize = sizeof(Value);
463c2c66affSColin Finck                         dwType = REG_DWORD;
464c2c66affSColin Finck                     }
465c2c66affSColin Finck                     else
466c2c66affSColin Finck                     {
467c2c66affSColin Finck                         dwSize = wcslen(lpszValue) * sizeof(WCHAR);
468c2c66affSColin Finck                         dwType = REG_SZ;
469c2c66affSColin Finck                     }
470c2c66affSColin Finck                 }
471c2c66affSColin Finck                 else
472c2c66affSColin Finck                 {
473c2c66affSColin Finck                     dwSize = 0;
474c2c66affSColin Finck                     dwType = REG_DWORD;
475c2c66affSColin Finck                 }
476c2c66affSColin Finck                 lRet = RegSetValueExW(hKey, lpszKey, 0, dwType, (LPBYTE)lpszValue, dwSize);
477c2c66affSColin Finck             }
478c2c66affSColin Finck             Free(lpszData);
479c2c66affSColin Finck             RegCloseKey(hKey);
480c2c66affSColin Finck             lpszSection += (wcslen(lpszSection) + 1);
481c2c66affSColin Finck         }
482c2c66affSColin Finck     }
483c2c66affSColin Finck     Free(lpszSections);
484c2c66affSColin Finck 
485c2c66affSColin Finck MigrationDone:
486c2c66affSColin Finck     Value = TRUE;
487c2c66affSColin Finck     RegSetValueExW(Globals.hKeyProgMan, L"IniMigrated", 0, REG_DWORD, (LPBYTE)&Value, sizeof(Value));
488c2c66affSColin Finck 
489c2c66affSColin Finck 
490c2c66affSColin Finck LoadSettings:
491c2c66affSColin Finck     /* Create the necessary registry keys for the Program Manager and load its settings from the registry */
492c2c66affSColin Finck 
493c2c66affSColin Finck     lRet = RegCreateKeyExW(Globals.hKeyProgMan,
494c2c66affSColin Finck                            L"Settings",
495c2c66affSColin Finck                            0,
496c2c66affSColin Finck                            NULL,
497c2c66affSColin Finck                            REG_OPTION_NON_VOLATILE,
498c2c66affSColin Finck                            KEY_READ | KEY_WRITE,
499c2c66affSColin Finck                            NULL,
500c2c66affSColin Finck                            &Globals.hKeyPMSettings,
501c2c66affSColin Finck                            NULL);
502c2c66affSColin Finck 
503c2c66affSColin Finck     lRet = RegCreateKeyExW(Globals.hKeyProgMan,
504c2c66affSColin Finck                            L"Common Groups",
505c2c66affSColin Finck                            0,
506c2c66affSColin Finck                            NULL,
507c2c66affSColin Finck                            REG_OPTION_NON_VOLATILE,
508c2c66affSColin Finck                            KEY_READ | KEY_WRITE,
509c2c66affSColin Finck                            NULL,
510c2c66affSColin Finck                            &Globals.hKeyPMCommonGroups,
511c2c66affSColin Finck                            NULL);
512c2c66affSColin Finck 
513c2c66affSColin Finck     lRet = RegCreateKeyExW(Globals.hKeyProgMan,
514c2c66affSColin Finck                            L"Groups",
515c2c66affSColin Finck                            0,
516c2c66affSColin Finck                            NULL,
517c2c66affSColin Finck                            REG_OPTION_NON_VOLATILE,
518c2c66affSColin Finck                            KEY_READ | KEY_WRITE,
519c2c66affSColin Finck                            NULL,
520c2c66affSColin Finck                            &Globals.hKeyPMAnsiGroups,
521c2c66affSColin Finck                            NULL);
522c2c66affSColin Finck 
523c2c66affSColin Finck     lRet = RegCreateKeyExW(Globals.hKeyProgMan,
524c2c66affSColin Finck                            L"UNICODE Groups",
525c2c66affSColin Finck                            0,
526c2c66affSColin Finck                            NULL,
527c2c66affSColin Finck                            REG_OPTION_NON_VOLATILE,
528c2c66affSColin Finck                            KEY_READ | KEY_WRITE,
529c2c66affSColin Finck                            NULL,
530c2c66affSColin Finck                            &Globals.hKeyPMUnicodeGroups,
531c2c66affSColin Finck                            NULL);
532c2c66affSColin Finck 
533c2c66affSColin Finck     lRet = RegCreateKeyExW(HKEY_CURRENT_USER,
534c2c66affSColin Finck                            L"Program Groups",
535c2c66affSColin Finck                            0,
536c2c66affSColin Finck                            NULL,
537c2c66affSColin Finck                            REG_OPTION_NON_VOLATILE,
538c2c66affSColin Finck                            KEY_READ | KEY_WRITE,
539c2c66affSColin Finck                            NULL,
540c2c66affSColin Finck                            &Globals.hKeyAnsiGroups,
541c2c66affSColin Finck                            NULL);
542c2c66affSColin Finck 
543c2c66affSColin Finck     lRet = RegCreateKeyExW(HKEY_CURRENT_USER,
544c2c66affSColin Finck                            L"UNICODE Program Groups",
545c2c66affSColin Finck                            0,
546c2c66affSColin Finck                            NULL,
547c2c66affSColin Finck                            REG_OPTION_NON_VOLATILE,
548c2c66affSColin Finck                            KEY_READ | KEY_WRITE,
549c2c66affSColin Finck                            NULL,
550c2c66affSColin Finck                            &Globals.hKeyUnicodeGroups,
551c2c66affSColin Finck                            NULL);
552c2c66affSColin Finck 
553c2c66affSColin Finck     lRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
554c2c66affSColin Finck                            L"SOFTWARE\\Program Groups",
555c2c66affSColin Finck                            0,
556c2c66affSColin Finck                            NULL,
557c2c66affSColin Finck                            REG_OPTION_NON_VOLATILE,
558c2c66affSColin Finck                            KEY_READ | KEY_WRITE,
559c2c66affSColin Finck                            NULL,
560c2c66affSColin Finck                            &Globals.hKeyCommonGroups,
561c2c66affSColin Finck                            NULL);
562c2c66affSColin Finck 
563c2c66affSColin Finck     dwSize = sizeof(Globals.bAutoArrange);
564c2c66affSColin Finck     RegQueryValueExW(Globals.hKeyPMSettings, L"AutoArrange", NULL, &dwType, (LPBYTE)&Globals.bAutoArrange, &dwSize);
565c2c66affSColin Finck 
566c2c66affSColin Finck     dwSize = sizeof(Globals.bMinOnRun);
567c2c66affSColin Finck     RegQueryValueExW(Globals.hKeyPMSettings, L"MinOnRun", NULL, &dwType, (LPBYTE)&Globals.bMinOnRun, &dwSize);
568c2c66affSColin Finck 
569c2c66affSColin Finck     dwSize = sizeof(Globals.bSaveSettings);
570c2c66affSColin Finck     RegQueryValueExW(Globals.hKeyPMSettings, L"SaveSettings", NULL, &dwType, (LPBYTE)&Globals.bSaveSettings, &dwSize);
571c2c66affSColin Finck 
572c2c66affSColin Finck     return TRUE;
573c2c66affSColin Finck }
574c2c66affSColin Finck 
575c2c66affSColin Finck static
576c2c66affSColin Finck BOOL
MAIN_SaveSettings(VOID)577c2c66affSColin Finck MAIN_SaveSettings(VOID)
578c2c66affSColin Finck {
579c2c66affSColin Finck     WINDOWPLACEMENT WndPl;
580c2c66affSColin Finck     DWORD dwSize;
581c2c66affSColin Finck     WCHAR buffer[100];
582c2c66affSColin Finck 
583c2c66affSColin Finck     WndPl.length = sizeof(WndPl);
584c2c66affSColin Finck     GetWindowPlacement(Globals.hMainWnd, &WndPl);
585c2c66affSColin Finck     StringCbPrintfW(buffer, sizeof(buffer),
586c2c66affSColin Finck                     L"%d %d %d %d %d",
587c2c66affSColin Finck                     WndPl.rcNormalPosition.left,
588c2c66affSColin Finck                     WndPl.rcNormalPosition.top,
589c2c66affSColin Finck                     WndPl.rcNormalPosition.right,
590c2c66affSColin Finck                     WndPl.rcNormalPosition.bottom,
591c2c66affSColin Finck                     WndPl.showCmd);
592c2c66affSColin Finck 
593c2c66affSColin Finck     dwSize = wcslen(buffer) * sizeof(WCHAR);
594c2c66affSColin Finck     RegSetValueExW(Globals.hKeyPMSettings, L"Window", 0, REG_SZ, (LPBYTE)buffer, dwSize);
595c2c66affSColin Finck 
596c2c66affSColin Finck     return TRUE;
597c2c66affSColin Finck }
598c2c66affSColin Finck 
599c2c66affSColin Finck 
600c2c66affSColin Finck /***********************************************************************
601c2c66affSColin Finck  *
602c2c66affSColin Finck  *           WinMain
603c2c66affSColin Finck  */
604c2c66affSColin Finck 
wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR lpCmdLine,INT nCmdShow)605c2c66affSColin Finck INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, INT nCmdShow)
606c2c66affSColin Finck {
607c2c66affSColin Finck     MSG msg;
608c2c66affSColin Finck     INITCOMMONCONTROLSEX icex;
609c2c66affSColin Finck 
610c2c66affSColin Finck     /*
611c2c66affSColin Finck      * Set our shutdown parameters: we want to shutdown the very last,
612c2c66affSColin Finck      * but before any TaskMgr instance (which has a shutdown level of 1).
613c2c66affSColin Finck      */
614c2c66affSColin Finck     SetProcessShutdownParameters(2, 0);
615c2c66affSColin Finck 
616c2c66affSColin Finck     Globals.hInstance    = hInstance;
617c2c66affSColin Finck     Globals.hGroups      = NULL;
618c2c66affSColin Finck     Globals.hActiveGroup = NULL;
619c2c66affSColin Finck 
620c2c66affSColin Finck     /* Load Program Manager's settings */
621c2c66affSColin Finck     MAIN_LoadSettings();
622c2c66affSColin Finck 
623c2c66affSColin Finck     /* Load the default icons */
624c2c66affSColin Finck     Globals.hDefaultIcon       = LoadIconW(NULL, MAKEINTRESOURCEW(IDI_WINLOGO));
625c2c66affSColin Finck     Globals.hMainIcon          = LoadIconW(Globals.hInstance, MAKEINTRESOURCEW(IDI_APPICON));
626c2c66affSColin Finck     Globals.hPersonalGroupIcon = LoadIconW(Globals.hInstance, MAKEINTRESOURCEW(IDI_GROUP_PERSONAL_ICON));
627c2c66affSColin Finck     Globals.hCommonGroupIcon   = LoadIconW(Globals.hInstance, MAKEINTRESOURCEW(IDI_GROUP_COMMON_ICON));
628c2c66affSColin Finck 
629c2c66affSColin Finck     /* Initialize the common controls */
630c2c66affSColin Finck     icex.dwSize = sizeof(icex);
631c2c66affSColin Finck     icex.dwICC  = ICC_HOTKEY_CLASS | ICC_LISTVIEW_CLASSES; // | ICC_STANDARD_CLASSES;
632c2c66affSColin Finck     InitCommonControlsEx(&icex);
633c2c66affSColin Finck 
634c2c66affSColin Finck     /* Register the window classes */
635c2c66affSColin Finck     if (!hPrevInstance) // FIXME: Unused on Win32!
636c2c66affSColin Finck     {
637c2c66affSColin Finck         if (!MAIN_RegisterMainWinClass())   goto Quit;
638c2c66affSColin Finck         if (!GROUP_RegisterGroupWinClass()) goto Quit;
639c2c66affSColin Finck     }
640c2c66affSColin Finck 
641c2c66affSColin Finck     /* Set up the strings, the main window, the accelerators, the menu, and the MDI child window */
642c2c66affSColin Finck     STRING_LoadStrings();
643c2c66affSColin Finck     MAIN_CreateMainWindow();
644c2c66affSColin Finck     Globals.hAccel = LoadAcceleratorsW(Globals.hInstance, MAKEINTRESOURCEW(IDA_ACCEL));
645c2c66affSColin Finck     STRING_LoadMenus();
646c2c66affSColin Finck     MAIN_CreateMDIWindow();
647c2c66affSColin Finck 
648c2c66affSColin Finck     /* Load all the groups */
649c2c66affSColin Finck     // MAIN_CreateGroups();
650c2c66affSColin Finck     MAIN_LoadGroups();
651c2c66affSColin Finck 
652c2c66affSColin Finck     /* Load the Startup group: start the initial applications */
653c2c66affSColin Finck     MAIN_AutoStart();
654c2c66affSColin Finck 
655c2c66affSColin Finck     /* Message loop */
656c2c66affSColin Finck     while (GetMessageW(&msg, NULL, 0, 0))
657c2c66affSColin Finck     {
658c2c66affSColin Finck         if (!TranslateMDISysAccel(Globals.hMDIWnd, &msg) &&
659c2c66affSColin Finck             !TranslateAcceleratorW(Globals.hMainWnd, Globals.hAccel, &msg))
660c2c66affSColin Finck         {
661c2c66affSColin Finck             TranslateMessage(&msg);
662c2c66affSColin Finck             DispatchMessageW(&msg);
663c2c66affSColin Finck         }
664c2c66affSColin Finck     }
665c2c66affSColin Finck 
666c2c66affSColin Finck Quit:
667c2c66affSColin Finck 
668c2c66affSColin Finck     /* Save the settings, close the registry keys and quit */
669c2c66affSColin Finck 
670c2c66affSColin Finck     // MAIN_SaveSettings();
671c2c66affSColin Finck     RegCloseKey(Globals.hKeyCommonGroups);
672c2c66affSColin Finck     RegCloseKey(Globals.hKeyUnicodeGroups);
673c2c66affSColin Finck     RegCloseKey(Globals.hKeyAnsiGroups);
674c2c66affSColin Finck     RegCloseKey(Globals.hKeyPMUnicodeGroups);
675c2c66affSColin Finck     RegCloseKey(Globals.hKeyPMAnsiGroups);
676c2c66affSColin Finck     RegCloseKey(Globals.hKeyPMCommonGroups);
677c2c66affSColin Finck     RegCloseKey(Globals.hKeyPMSettings);
678c2c66affSColin Finck     RegCloseKey(Globals.hKeyProgMan);
679c2c66affSColin Finck 
680c2c66affSColin Finck     return 0;
681c2c66affSColin Finck }
682c2c66affSColin Finck 
683c2c66affSColin Finck /***********************************************************************
684c2c66affSColin Finck  *
685c2c66affSColin Finck  *           MAIN_CreateGroups
686c2c66affSColin Finck  */
687c2c66affSColin Finck 
688c2c66affSColin Finck #if 0
689c2c66affSColin Finck static VOID MAIN_CreateGroups(VOID)
690c2c66affSColin Finck {
691c2c66affSColin Finck   CHAR buffer[BUFFER_SIZE];
692c2c66affSColin Finck   CHAR szPath[MAX_PATHNAME_LEN];
693c2c66affSColin Finck   CHAR key[20], *ptr;
694c2c66affSColin Finck 
695c2c66affSColin Finck   /* Initialize groups according the `Order' entry of `progman.ini' */
696c2c66affSColin Finck   GetPrivateProfileStringA("Settings", "Order", "", buffer, sizeof(buffer), Globals.lpszIniFile);
697c2c66affSColin Finck   ptr = buffer;
698c2c66affSColin Finck   while (ptr < buffer + sizeof(buffer))
699c2c66affSColin Finck     {
700c2c66affSColin Finck       int num, skip, ret;
701c2c66affSColin Finck       ret = sscanf(ptr, "%d%n", &num, &skip);
702c2c66affSColin Finck       if (ret == 0)
703c2c66affSColin Finck 	MAIN_MessageBoxIDS_s(IDS_FILE_READ_ERROR_s, Globals.lpszIniFile, IDS_ERROR, MB_OK);
704c2c66affSColin Finck       if (ret != 1) break;
705c2c66affSColin Finck 
706c2c66affSColin Finck       sprintf(key, "Group%d", num);
707c2c66affSColin Finck       GetPrivateProfileStringA("Groups", key, "", szPath,
708c2c66affSColin Finck 			      sizeof(szPath), Globals.lpszIniFile);
709c2c66affSColin Finck       if (!szPath[0]) continue;
710c2c66affSColin Finck 
711c2c66affSColin Finck       GRPFILE_ReadGroupFile(szPath);
712c2c66affSColin Finck 
713c2c66affSColin Finck       ptr += skip;
714c2c66affSColin Finck     }
715c2c66affSColin Finck   /* FIXME initialize other groups, not enumerated by `Order' */
716c2c66affSColin Finck }
717c2c66affSColin Finck #endif
718c2c66affSColin Finck 
MAIN_LoadGroups(VOID)719c2c66affSColin Finck static VOID MAIN_LoadGroups(VOID)
720c2c66affSColin Finck {
721c2c66affSColin Finck }
722c2c66affSColin Finck 
723c2c66affSColin Finck /***********************************************************************
724c2c66affSColin Finck  *
725c2c66affSColin Finck  *           MAIN_AutoStart
726c2c66affSColin Finck  */
727c2c66affSColin Finck 
MAIN_AutoStart(VOID)728c2c66affSColin Finck static VOID MAIN_AutoStart(VOID)
729c2c66affSColin Finck {
730c2c66affSColin Finck     LONG lRet;
731c2c66affSColin Finck     DWORD dwSize;
732c2c66affSColin Finck     DWORD dwType;
733c2c66affSColin Finck 
734c2c66affSColin Finck     PROGGROUP* hGroup;
735c2c66affSColin Finck     PROGRAM* hProgram;
736c2c66affSColin Finck 
737c2c66affSColin Finck     WCHAR buffer[BUFFER_SIZE];
738c2c66affSColin Finck 
739c2c66affSColin Finck     dwSize = sizeof(buffer);
740c2c66affSColin Finck     lRet = RegQueryValueExW(Globals.hKeyPMSettings, L"Startup", NULL, &dwType, (LPBYTE)buffer, &dwSize);
741c2c66affSColin Finck     if (lRet != ERROR_SUCCESS || dwType != REG_SZ)
742c2c66affSColin Finck         return;
743c2c66affSColin Finck 
744c2c66affSColin Finck     for (hGroup = Globals.hGroups; hGroup; hGroup = hGroup->hNext)
745c2c66affSColin Finck     {
746c2c66affSColin Finck         if (_wcsicmp(buffer, hGroup->hName) == 0)
747c2c66affSColin Finck         {
748c2c66affSColin Finck             for (hProgram = hGroup->hPrograms; hProgram; hProgram = hProgram->hNext)
749c2c66affSColin Finck                 PROGRAM_ExecuteProgram(hProgram);
750c2c66affSColin Finck         }
751c2c66affSColin Finck     }
752c2c66affSColin Finck }
753c2c66affSColin Finck 
754c2c66affSColin Finck /***********************************************************************
755c2c66affSColin Finck  *
756c2c66affSColin Finck  *           MAIN_MainWndProc
757c2c66affSColin Finck  */
758c2c66affSColin Finck 
MAIN_MainWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)759c2c66affSColin Finck static LRESULT CALLBACK MAIN_MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
760c2c66affSColin Finck {
761c2c66affSColin Finck     switch (uMsg)
762c2c66affSColin Finck     {
763c2c66affSColin Finck         case WM_INITMENU:
764c2c66affSColin Finck         {
765c2c66affSColin Finck             PROGGROUP* hActiveGroup = GROUP_ActiveGroup();
766c2c66affSColin Finck             if (hActiveGroup)
767c2c66affSColin Finck             {
768c2c66affSColin Finck                 if (PROGRAM_ActiveProgram(hActiveGroup))
769c2c66affSColin Finck                 {
770c2c66affSColin Finck                     EnableMenuItem(Globals.hFileMenu, PM_OPEN, MF_ENABLED);
771c2c66affSColin Finck                     EnableMenuItem(Globals.hFileMenu, PM_MOVE, MF_ENABLED);
772c2c66affSColin Finck                     EnableMenuItem(Globals.hFileMenu, PM_COPY, MF_ENABLED);
773c2c66affSColin Finck                     EnableMenuItem(Globals.hFileMenu, PM_DELETE    , MF_ENABLED);
774c2c66affSColin Finck                     EnableMenuItem(Globals.hFileMenu, PM_ATTRIBUTES, MF_ENABLED);
775c2c66affSColin Finck                 }
776c2c66affSColin Finck                 else
777c2c66affSColin Finck                 {
778c2c66affSColin Finck                     if (!hActiveGroup->hWnd || IsIconic(hActiveGroup->hWnd))
779c2c66affSColin Finck                         EnableMenuItem(Globals.hFileMenu, PM_OPEN, MF_ENABLED);
780c2c66affSColin Finck                     else
781c2c66affSColin Finck                         EnableMenuItem(Globals.hFileMenu, PM_OPEN, MF_GRAYED);
782c2c66affSColin Finck 
783c2c66affSColin Finck                     EnableMenuItem(Globals.hFileMenu, PM_MOVE, MF_GRAYED);
784c2c66affSColin Finck                     EnableMenuItem(Globals.hFileMenu, PM_COPY, MF_GRAYED);
785c2c66affSColin Finck                     EnableMenuItem(Globals.hFileMenu, PM_DELETE    , MF_ENABLED);
786c2c66affSColin Finck                     EnableMenuItem(Globals.hFileMenu, PM_ATTRIBUTES, MF_ENABLED);
787c2c66affSColin Finck                 }
788c2c66affSColin Finck             }
789c2c66affSColin Finck             else
790c2c66affSColin Finck             {
791c2c66affSColin Finck                 EnableMenuItem(Globals.hFileMenu, PM_OPEN, MF_GRAYED);
792c2c66affSColin Finck                 EnableMenuItem(Globals.hFileMenu, PM_MOVE, MF_GRAYED);
793c2c66affSColin Finck                 EnableMenuItem(Globals.hFileMenu, PM_COPY, MF_GRAYED);
794c2c66affSColin Finck                 EnableMenuItem(Globals.hFileMenu, PM_DELETE    , MF_GRAYED);
795c2c66affSColin Finck                 EnableMenuItem(Globals.hFileMenu, PM_ATTRIBUTES, MF_GRAYED);
796c2c66affSColin Finck             }
797c2c66affSColin Finck 
798c2c66affSColin Finck             CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
799c2c66affSColin Finck                           MF_BYCOMMAND | (Globals.bAutoArrange  ? MF_CHECKED : MF_UNCHECKED));
800c2c66affSColin Finck             CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
801c2c66affSColin Finck                           MF_BYCOMMAND | (Globals.bMinOnRun     ? MF_CHECKED : MF_UNCHECKED));
802c2c66affSColin Finck             CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
803c2c66affSColin Finck                           MF_BYCOMMAND | (Globals.bSaveSettings ? MF_CHECKED : MF_UNCHECKED));
804c2c66affSColin Finck             break;
805c2c66affSColin Finck         }
806c2c66affSColin Finck 
807c2c66affSColin Finck         case WM_DESTROY:
808c2c66affSColin Finck             if (Globals.bSaveSettings)
809c2c66affSColin Finck                 MAIN_SaveSettings();
810c2c66affSColin Finck             PostQuitMessage(0);
811c2c66affSColin Finck             break;
812c2c66affSColin Finck 
813c2c66affSColin Finck         case WM_COMMAND:
814c2c66affSColin Finck             if (LOWORD(wParam) < PM_FIRST_CHILD)
815c2c66affSColin Finck                 MAIN_MenuCommand(hWnd, LOWORD(wParam), lParam);
816c2c66affSColin Finck             break;
817c2c66affSColin Finck     }
818c2c66affSColin Finck 
819c2c66affSColin Finck     return DefFrameProcW(hWnd, Globals.hMDIWnd, uMsg, wParam, lParam);
820c2c66affSColin Finck }
821c2c66affSColin Finck 
822c2c66affSColin Finck 
823c2c66affSColin Finck /***********************************************************************
824c2c66affSColin Finck  *
825c2c66affSColin Finck  *           MAIN_MenuCommand
826c2c66affSColin Finck  */
827c2c66affSColin Finck 
MAIN_MenuCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)828c2c66affSColin Finck static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
829c2c66affSColin Finck {
830c2c66affSColin Finck #if 0
831c2c66affSColin Finck   HLOCAL hActiveGroup    = GROUP_ActiveGroup();
832c2c66affSColin Finck   HLOCAL hActiveProgram  = PROGRAM_ActiveProgram(hActiveGroup);
833c2c66affSColin Finck   HWND   hActiveGroupWnd = GROUP_GroupWnd(hActiveGroup);
834c2c66affSColin Finck 
835c2c66affSColin Finck   switch(wParam)
836c2c66affSColin Finck     {
837c2c66affSColin Finck       /* Menu File */
838c2c66affSColin Finck     case PM_NEW:
839c2c66affSColin Finck       switch (DIALOG_New((hActiveGroupWnd && !IsIconic(hActiveGroupWnd)) ?
840c2c66affSColin Finck 			 PM_NEW_PROGRAM : PM_NEW_GROUP))
841c2c66affSColin Finck       {
842c2c66affSColin Finck       case PM_NEW_PROGRAM:
843c2c66affSColin Finck 	if (hActiveGroup) PROGRAM_NewProgram(hActiveGroup);
844c2c66affSColin Finck 	break;
845c2c66affSColin Finck 
846c2c66affSColin Finck       case PM_NEW_GROUP:
847c2c66affSColin Finck 	GROUP_NewGroup();
848c2c66affSColin Finck 	break;
849c2c66affSColin Finck       }
850c2c66affSColin Finck       break;
851c2c66affSColin Finck 
852c2c66affSColin Finck 
853c2c66affSColin Finck     case PM_DELETE:
854c2c66affSColin Finck       if (hActiveProgram)
855c2c66affSColin Finck 	{
856c2c66affSColin Finck 	if (DIALOG_Delete(IDS_DELETE_PROGRAM_s, PROGRAM_ProgramName(hActiveProgram)))
857c2c66affSColin Finck 	  PROGRAM_DeleteProgram(hActiveProgram, TRUE);
858c2c66affSColin Finck 	}
859c2c66affSColin Finck       else if (hActiveGroup)
860c2c66affSColin Finck 	{
861c2c66affSColin Finck 	if (DIALOG_Delete(IDS_DELETE_GROUP_s, GROUP_GroupName(hActiveGroup)))
862c2c66affSColin Finck 	  GROUP_DeleteGroup(hActiveGroup);
863c2c66affSColin Finck 	}
864c2c66affSColin Finck       break;
865c2c66affSColin Finck 
866c2c66affSColin Finck 
867c2c66affSColin Finck 
868c2c66affSColin Finck     case PM_SAVE_SETTINGS:
869c2c66affSColin Finck       Globals.bSaveSettings = !Globals.bSaveSettings;
870c2c66affSColin Finck       CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
871c2c66affSColin Finck 		    MF_BYCOMMAND | (Globals.bSaveSettings ?
872c2c66affSColin Finck 				    MF_CHECKED : MF_UNCHECKED));
873c2c66affSColin Finck       WritePrivateProfileStringA("Settings", "SaveSettings",
874c2c66affSColin Finck 				Globals.bSaveSettings ? "1" : "0",
875c2c66affSColin Finck 				Globals.lpszIniFile);
876c2c66affSColin Finck       WritePrivateProfileStringA(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
877c2c66affSColin Finck       break;
878c2c66affSColin Finck 
879c2c66affSColin Finck 
880c2c66affSColin Finck     case PM_ARRANGE:
881c2c66affSColin Finck 
882c2c66affSColin Finck       if (hActiveGroupWnd && !IsIconic(hActiveGroupWnd))
883c2c66affSColin Finck 	ArrangeIconicWindows(hActiveGroupWnd);
884c2c66affSColin Finck       else
885c2c66affSColin Finck 	SendMessageW(Globals.hMDIWnd, WM_MDIICONARRANGE, 0, 0);
886c2c66affSColin Finck       break;
887c2c66affSColin Finck 
888c2c66affSColin Finck     }
889c2c66affSColin Finck 
890c2c66affSColin Finck 
891c2c66affSColin Finck 
892c2c66affSColin Finck 
893c2c66affSColin Finck #endif
894c2c66affSColin Finck 
895c2c66affSColin Finck     DWORD Value;
896c2c66affSColin Finck 
897c2c66affSColin Finck     PROGGROUP* hActiveGroup;
898c2c66affSColin Finck     PROGRAM* hActiveProgram;
899c2c66affSColin Finck     HWND hActiveGroupWnd;
900c2c66affSColin Finck 
901c2c66affSColin Finck     hActiveGroup = GROUP_ActiveGroup();
902c2c66affSColin Finck     hActiveProgram = PROGRAM_ActiveProgram(hActiveGroup);
903c2c66affSColin Finck     hActiveGroupWnd = (hActiveGroup ? hActiveGroup->hWnd : NULL);
904c2c66affSColin Finck 
905c2c66affSColin Finck     switch (wParam)
906c2c66affSColin Finck     {
907c2c66affSColin Finck         /* Menu File */
908c2c66affSColin Finck 
909c2c66affSColin Finck         case PM_NEW:
910c2c66affSColin Finck         {
911c2c66affSColin Finck             BOOL Success;
912c2c66affSColin Finck             INT nResult;
913c2c66affSColin Finck 
914c2c66affSColin Finck             if (!hActiveGroupWnd || IsIconic(hActiveGroupWnd))
915c2c66affSColin Finck                 Success = DIALOG_New(PM_NEW_GROUP, &nResult);
916c2c66affSColin Finck             else
917c2c66affSColin Finck                 Success = DIALOG_New(PM_NEW_PROGRAM, &nResult);
918c2c66affSColin Finck             if (!Success)
919c2c66affSColin Finck                 break;
920c2c66affSColin Finck 
921c2c66affSColin Finck             if (nResult & 1)
922c2c66affSColin Finck             {
923c2c66affSColin Finck                 GROUPFORMAT format;
924c2c66affSColin Finck                 BOOL bIsCommonGroup;
925c2c66affSColin Finck 
926c2c66affSColin Finck                 format = (nResult & 0xC) >> 2;
927c2c66affSColin Finck                 bIsCommonGroup = (nResult & 2) != 0;
928c2c66affSColin Finck                 GROUP_NewGroup(format, bIsCommonGroup);
929c2c66affSColin Finck             }
930c2c66affSColin Finck             else if (hActiveGroup)
931c2c66affSColin Finck             {
932c2c66affSColin Finck                 PROGRAM_NewProgram(hActiveGroup);
933c2c66affSColin Finck             }
934c2c66affSColin Finck 
935c2c66affSColin Finck             break;
936c2c66affSColin Finck         }
937c2c66affSColin Finck 
938c2c66affSColin Finck         case PM_OPEN:
939c2c66affSColin Finck             if (hActiveProgram)
940c2c66affSColin Finck                 PROGRAM_ExecuteProgram(hActiveProgram);
941c2c66affSColin Finck             else if (hActiveGroupWnd)
942c2c66affSColin Finck                 OpenIcon(hActiveGroupWnd);
943c2c66affSColin Finck             break;
944c2c66affSColin Finck 
945c2c66affSColin Finck         case PM_MOVE:
946c2c66affSColin Finck         case PM_COPY:
947c2c66affSColin Finck             if (hActiveProgram)
948c2c66affSColin Finck                 PROGRAM_CopyMoveProgram(hActiveProgram, wParam == PM_MOVE);
949c2c66affSColin Finck             break;
950c2c66affSColin Finck 
951c2c66affSColin Finck         case PM_DELETE:
952c2c66affSColin Finck         {
953c2c66affSColin Finck             if (hActiveProgram)
954c2c66affSColin Finck             {
955c2c66affSColin Finck                 if (DIALOG_Delete(IDS_DELETE_PROGRAM_s, hActiveProgram->hName))
956c2c66affSColin Finck                     PROGRAM_DeleteProgram(hActiveProgram, TRUE);
957c2c66affSColin Finck             }
958c2c66affSColin Finck             else if (hActiveGroup && DIALOG_Delete(IDS_DELETE_GROUP_s, hActiveGroup->hName))
959c2c66affSColin Finck             {
960c2c66affSColin Finck                 GROUP_DeleteGroup(hActiveGroup);
961c2c66affSColin Finck             }
962c2c66affSColin Finck             break;
963c2c66affSColin Finck         }
964c2c66affSColin Finck 
965c2c66affSColin Finck         case PM_ATTRIBUTES:
966c2c66affSColin Finck             if (hActiveProgram)
967c2c66affSColin Finck                 PROGRAM_ModifyProgram(hActiveProgram);
968c2c66affSColin Finck             else if (hActiveGroup)
969c2c66affSColin Finck                 GROUP_ModifyGroup(hActiveGroup);
970c2c66affSColin Finck             break;
971c2c66affSColin Finck 
972c2c66affSColin Finck         case PM_EXECUTE:
973c2c66affSColin Finck             DIALOG_Execute();
974c2c66affSColin Finck             break;
975c2c66affSColin Finck 
976c2c66affSColin Finck         case PM_EXIT:
977c2c66affSColin Finck             // MAIN_SaveSettings();
978c2c66affSColin Finck             PostQuitMessage(0);
979c2c66affSColin Finck             break;
980c2c66affSColin Finck 
981c2c66affSColin Finck 
982c2c66affSColin Finck         /* Menu Options */
983c2c66affSColin Finck 
984c2c66affSColin Finck         case PM_AUTO_ARRANGE:
985c2c66affSColin Finck             Globals.bAutoArrange = !Globals.bAutoArrange;
986c2c66affSColin Finck             CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
987c2c66affSColin Finck                           MF_BYCOMMAND | (Globals.bAutoArrange ? MF_CHECKED : MF_UNCHECKED));
988c2c66affSColin Finck             Value = Globals.bAutoArrange;
989c2c66affSColin Finck             RegSetValueExW(Globals.hKeyPMSettings, L"AutoArrange", 0, REG_DWORD, (LPBYTE)&Value, sizeof(Value));
990c2c66affSColin Finck             break;
991c2c66affSColin Finck 
992c2c66affSColin Finck         case PM_MIN_ON_RUN:
993c2c66affSColin Finck             Globals.bMinOnRun = !Globals.bMinOnRun;
994c2c66affSColin Finck             CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
995c2c66affSColin Finck                           MF_BYCOMMAND | (Globals.bMinOnRun ? MF_CHECKED : MF_UNCHECKED));
996c2c66affSColin Finck             Value = Globals.bMinOnRun;
997c2c66affSColin Finck             RegSetValueExW(Globals.hKeyPMSettings, L"MinOnRun", 0, REG_DWORD, (LPBYTE)&Value, sizeof(Value));
998c2c66affSColin Finck             break;
999c2c66affSColin Finck 
1000c2c66affSColin Finck         case PM_SAVE_SETTINGS:
1001c2c66affSColin Finck             Globals.bSaveSettings = !Globals.bSaveSettings;
1002c2c66affSColin Finck             CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
1003c2c66affSColin Finck                           MF_BYCOMMAND | (Globals.bSaveSettings ? MF_CHECKED : MF_UNCHECKED));
1004c2c66affSColin Finck             Value = Globals.bSaveSettings;
1005c2c66affSColin Finck             RegSetValueExW(Globals.hKeyPMSettings, L"SaveSettings", 0, REG_DWORD, (LPBYTE)&Value, sizeof(Value));
1006c2c66affSColin Finck             break;
1007c2c66affSColin Finck 
1008c2c66affSColin Finck         case PM_SAVE_SETTINGS_NOW:
1009c2c66affSColin Finck             MAIN_SaveSettings();
1010c2c66affSColin Finck             break;
1011c2c66affSColin Finck 
1012c2c66affSColin Finck 
1013c2c66affSColin Finck         /* Menu Windows */
1014c2c66affSColin Finck 
1015c2c66affSColin Finck         case PM_OVERLAP:
1016c2c66affSColin Finck             SendMessageW(Globals.hMDIWnd, WM_MDICASCADE, 0, 0);
1017c2c66affSColin Finck             break;
1018c2c66affSColin Finck 
1019c2c66affSColin Finck         case PM_SIDE_BY_SIDE:
1020c2c66affSColin Finck             SendMessageW(Globals.hMDIWnd, WM_MDITILE, MDITILE_VERTICAL, 0);
1021c2c66affSColin Finck             break;
1022c2c66affSColin Finck 
1023c2c66affSColin Finck         case PM_ARRANGE:
1024c2c66affSColin Finck             if (!hActiveGroupWnd || IsIconic(hActiveGroupWnd))
1025c2c66affSColin Finck                 SendMessageW(Globals.hMDIWnd, WM_MDIICONARRANGE, 0, 0);
1026c2c66affSColin Finck             else
1027c2c66affSColin Finck                 SendMessageA(hActiveGroup->hListView, LVM_ARRANGE, 0, 0);
1028c2c66affSColin Finck             break;
1029c2c66affSColin Finck 
1030c2c66affSColin Finck 
1031c2c66affSColin Finck         /* Menu Help */
1032c2c66affSColin Finck 
1033c2c66affSColin Finck         case PM_CONTENTS:
1034c2c66affSColin Finck             if (!WinHelpW(Globals.hMainWnd, L"progman.hlp", HELP_CONTENTS, 0))
1035c2c66affSColin Finck                 MAIN_MessageBoxIDS(IDS_WINHELP_ERROR, IDS_ERROR, MB_OK);
1036c2c66affSColin Finck             break;
1037c2c66affSColin Finck 
1038c2c66affSColin Finck         case PM_ABOUT:
1039c2c66affSColin Finck             ShellAboutW(hWnd, szTitle, NULL, Globals.hMainIcon);
1040c2c66affSColin Finck             break;
1041c2c66affSColin Finck 
1042c2c66affSColin Finck         default:
1043c2c66affSColin Finck             MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
1044c2c66affSColin Finck             break;
1045c2c66affSColin Finck     }
1046c2c66affSColin Finck 
1047c2c66affSColin Finck }
1048c2c66affSColin Finck 
1049c2c66affSColin Finck /***********************************************************************
1050c2c66affSColin Finck  *
1051c2c66affSColin Finck  *           MAIN_RegisterMainWinClass
1052c2c66affSColin Finck  */
1053c2c66affSColin Finck 
MAIN_RegisterMainWinClass(VOID)1054c2c66affSColin Finck static ATOM MAIN_RegisterMainWinClass(VOID)
1055c2c66affSColin Finck {
1056c2c66affSColin Finck     WNDCLASSW wndClass;
1057c2c66affSColin Finck 
1058c2c66affSColin Finck     wndClass.style         = CS_HREDRAW | CS_VREDRAW;
1059c2c66affSColin Finck     wndClass.lpfnWndProc   = MAIN_MainWndProc;
1060c2c66affSColin Finck     wndClass.cbClsExtra    = 0;
1061c2c66affSColin Finck     wndClass.cbWndExtra    = 0;
1062c2c66affSColin Finck     wndClass.hInstance     = Globals.hInstance;
1063c2c66affSColin Finck     wndClass.hIcon         = Globals.hMainIcon;
1064*1a102501SOleg Dubinskiy     wndClass.hCursor       = LoadCursorW(NULL, IDC_ARROW);
1065c2c66affSColin Finck     wndClass.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
1066c2c66affSColin Finck     wndClass.lpszMenuName  = NULL;
1067c2c66affSColin Finck     wndClass.lpszClassName = STRING_MAIN_WIN_CLASS_NAME;
1068c2c66affSColin Finck 
1069c2c66affSColin Finck     return RegisterClassW(&wndClass);
1070c2c66affSColin Finck }
1071c2c66affSColin Finck 
1072c2c66affSColin Finck /***********************************************************************
1073c2c66affSColin Finck  *
1074c2c66affSColin Finck  *           MAIN_CreateMainWindow
1075c2c66affSColin Finck  */
1076c2c66affSColin Finck 
MAIN_CreateMainWindow(VOID)1077c2c66affSColin Finck static VOID MAIN_CreateMainWindow(VOID)
1078c2c66affSColin Finck {
1079c2c66affSColin Finck     INT left, top, right, bottom;
1080c2c66affSColin Finck     INT width, height;
1081c2c66affSColin Finck     INT nCmdShow;
1082c2c66affSColin Finck     WCHAR buffer[100];
1083c2c66affSColin Finck 
1084c2c66affSColin Finck     LONG lRet;
1085c2c66affSColin Finck     DWORD dwSize;
1086c2c66affSColin Finck     DWORD dwType;
1087c2c66affSColin Finck 
1088c2c66affSColin Finck     Globals.hMDIWnd   = NULL;
1089c2c66affSColin Finck     Globals.hMainMenu = NULL;
1090c2c66affSColin Finck 
1091c2c66affSColin Finck     /* Get the geometry of the main window */
1092c2c66affSColin Finck     dwSize = sizeof(buffer);
1093c2c66affSColin Finck     lRet = RegQueryValueExW(Globals.hKeyPMSettings, L"Window", NULL, &dwType, (LPBYTE)buffer, &dwSize);
1094c2c66affSColin Finck     if (lRet != ERROR_SUCCESS || dwType != REG_SZ)
1095c2c66affSColin Finck         buffer[0] = '\0';
1096c2c66affSColin Finck 
1097c2c66affSColin Finck     if (swscanf(buffer, L"%d %d %d %d %d", &left, &top, &right, &bottom, &nCmdShow) == 5)
1098c2c66affSColin Finck     {
1099c2c66affSColin Finck         width  = right  - left;
1100c2c66affSColin Finck         height = bottom - top;
1101c2c66affSColin Finck     }
1102c2c66affSColin Finck     else
1103c2c66affSColin Finck     {
1104c2c66affSColin Finck         left = top = width = height = CW_USEDEFAULT;
1105c2c66affSColin Finck         nCmdShow = SW_SHOWNORMAL;
1106c2c66affSColin Finck     }
1107c2c66affSColin Finck 
1108c2c66affSColin Finck     /* Create the main window */
1109c2c66affSColin Finck     Globals.hMainWnd =
1110c2c66affSColin Finck         CreateWindowW(STRING_MAIN_WIN_CLASS_NAME,
1111c2c66affSColin Finck                       szTitle,
1112c2c66affSColin Finck                       WS_OVERLAPPEDWINDOW, // /* | WS_CLIPSIBLINGS | WS_CLIPCHILDREN */
1113c2c66affSColin Finck                       left, top, width, height,
1114c2c66affSColin Finck                       NULL, NULL,
1115c2c66affSColin Finck                       Globals.hInstance,
1116c2c66affSColin Finck                       NULL);
1117c2c66affSColin Finck 
1118c2c66affSColin Finck     MAIN_SetMainWindowTitle();
1119c2c66affSColin Finck     ShowWindow(Globals.hMainWnd, nCmdShow);
1120c2c66affSColin Finck     UpdateWindow(Globals.hMainWnd);
1121c2c66affSColin Finck }
1122c2c66affSColin Finck 
1123c2c66affSColin Finck /***********************************************************************
1124c2c66affSColin Finck  *
1125c2c66affSColin Finck  *           MAIN_CreateMDIWindow
1126c2c66affSColin Finck  */
1127c2c66affSColin Finck 
MAIN_CreateMDIWindow(VOID)1128c2c66affSColin Finck static VOID MAIN_CreateMDIWindow(VOID)
1129c2c66affSColin Finck {
1130c2c66affSColin Finck     CLIENTCREATESTRUCT ccs;
1131c2c66affSColin Finck     RECT rect;
1132c2c66affSColin Finck 
1133c2c66affSColin Finck     /* Get the geometry of the MDI window */
1134c2c66affSColin Finck     GetClientRect(Globals.hMainWnd, &rect);
1135c2c66affSColin Finck 
1136c2c66affSColin Finck     ccs.hWindowMenu  = Globals.hWindowsMenu;
1137c2c66affSColin Finck     ccs.idFirstChild = PM_FIRST_CHILD;
1138c2c66affSColin Finck 
1139c2c66affSColin Finck     /* Create MDI Window */
1140c2c66affSColin Finck     Globals.hMDIWnd =
1141c2c66affSColin Finck         CreateWindowW(WC_MDICLIENT, NULL, WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL, // WS_CHILDWINDOW | ...
1142c2c66affSColin Finck                       rect.left, rect.top,
1143c2c66affSColin Finck                       rect.right - rect.left, rect.bottom - rect.top,
1144c2c66affSColin Finck                       Globals.hMainWnd, 0,
1145c2c66affSColin Finck                       Globals.hInstance, &ccs);
1146c2c66affSColin Finck 
1147c2c66affSColin Finck     /* Reset the background of the MDI client window (default: COLOR_APPWORKSPACE + 1) */
1148c2c66affSColin Finck     SetClassLongPtrW(Globals.hMDIWnd, GCLP_HBRBACKGROUND, (COLOR_WINDOW + 1));
1149c2c66affSColin Finck 
1150c2c66affSColin Finck     ShowWindow(Globals.hMDIWnd, SW_SHOW);
1151c2c66affSColin Finck     UpdateWindow(Globals.hMDIWnd);
1152c2c66affSColin Finck }
1153c2c66affSColin Finck 
1154c2c66affSColin Finck /**********************************************************************/
1155c2c66affSColin Finck /***********************************************************************
1156c2c66affSColin Finck  *
1157c2c66affSColin Finck  *           MAIN_MessageBoxIDS
1158c2c66affSColin Finck  */
MAIN_MessageBoxIDS(UINT ids_text,UINT ids_title,WORD type)1159c2c66affSColin Finck INT MAIN_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type)
1160c2c66affSColin Finck {
1161c2c66affSColin Finck     WCHAR text[MAX_STRING_LEN];
1162c2c66affSColin Finck     WCHAR title[MAX_STRING_LEN];
1163c2c66affSColin Finck 
1164c2c66affSColin Finck     LoadStringW(Globals.hInstance, ids_text , text , ARRAYSIZE(text));
1165c2c66affSColin Finck     LoadStringW(Globals.hInstance, ids_title, title, ARRAYSIZE(title));
1166c2c66affSColin Finck 
1167c2c66affSColin Finck     return MessageBoxW(Globals.hMainWnd, text, title, type);
1168c2c66affSColin Finck }
1169c2c66affSColin Finck 
1170c2c66affSColin Finck /***********************************************************************
1171c2c66affSColin Finck  *
1172c2c66affSColin Finck  *           MAIN_MessageBoxIDS_s
1173c2c66affSColin Finck  */
MAIN_MessageBoxIDS_s(UINT ids_text,LPCWSTR str,UINT ids_title,WORD type)1174c2c66affSColin Finck INT MAIN_MessageBoxIDS_s(UINT ids_text, LPCWSTR str, UINT ids_title, WORD type)
1175c2c66affSColin Finck {
1176c2c66affSColin Finck     WCHAR text[MAX_STRING_LEN];
1177c2c66affSColin Finck     WCHAR title[MAX_STRING_LEN];
1178c2c66affSColin Finck     WCHAR newtext[MAX_STRING_LEN + MAX_PATHNAME_LEN];
1179c2c66affSColin Finck 
1180c2c66affSColin Finck     LoadStringW(Globals.hInstance, ids_text , text , ARRAYSIZE(text));
1181c2c66affSColin Finck     LoadStringW(Globals.hInstance, ids_title, title, ARRAYSIZE(title));
1182c2c66affSColin Finck     wsprintfW(newtext, text, str);
1183c2c66affSColin Finck 
1184c2c66affSColin Finck     return MessageBoxW(Globals.hMainWnd, newtext, title, type);
1185c2c66affSColin Finck }
1186c2c66affSColin Finck 
1187c2c66affSColin Finck /***********************************************************************
1188c2c66affSColin Finck  *
1189c2c66affSColin Finck  *           MAIN_ReplaceString
1190c2c66affSColin Finck  */
1191c2c66affSColin Finck 
MAIN_ReplaceString(LPWSTR * string,LPWSTR replace)1192c2c66affSColin Finck VOID MAIN_ReplaceString(LPWSTR* string, LPWSTR replace)
1193c2c66affSColin Finck {
1194c2c66affSColin Finck     LPWSTR newstring;
1195c2c66affSColin Finck 
1196c2c66affSColin Finck     newstring = Alloc(HEAP_ZERO_MEMORY, (wcslen(replace) + 1) * sizeof(WCHAR));
1197c2c66affSColin Finck     if (newstring)
1198c2c66affSColin Finck     {
1199c2c66affSColin Finck         wcscpy(newstring, replace);
1200c2c66affSColin Finck         *string = newstring;
1201c2c66affSColin Finck     }
1202c2c66affSColin Finck     else
1203c2c66affSColin Finck     {
1204c2c66affSColin Finck         MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK);
1205c2c66affSColin Finck     }
1206c2c66affSColin Finck }
1207