Restore focus to the current control without selecting text.
[wine] / programs / progman / program.c
1 /*
2  * Program Manager
3  *
4  * Copyright 1996 Ulrich Schmid
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <string.h>
22 #include "windows.h"
23 #include "windowsx.h"
24 #include "progman.h"
25
26 /***********************************************************************
27  *
28  *           PROGRAM_ProgramWndProc
29  */
30
31 static LRESULT CALLBACK PROGRAM_ProgramWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
32 {
33   switch (msg)
34     {
35     case WM_NCLBUTTONDOWN:
36       {
37         HLOCAL  hProgram = (HLOCAL) GetWindowLong(hWnd, 0);
38         PROGRAM *program = LocalLock(hProgram);
39         PROGGROUP   *group   = LocalLock(program->hGroup);
40         group->hActiveProgram = hProgram;
41         EnableMenuItem(Globals.hFileMenu, PM_MOVE , MF_ENABLED);
42         EnableMenuItem(Globals.hFileMenu, PM_COPY , MF_ENABLED);
43         break;
44       }
45     case WM_NCLBUTTONDBLCLK:
46       {
47         PROGRAM_ExecuteProgram((HLOCAL) GetWindowLong(hWnd, 0));
48         return(0);
49       }
50
51     case WM_PAINTICON:
52     case WM_NCPAINT:
53       {
54         PROGRAM *program;
55         PAINTSTRUCT      ps;
56         HDC              hdc;
57         hdc     = BeginPaint(hWnd,&ps);
58         program = LocalLock((HLOCAL) GetWindowLong(hWnd, 0));
59         if (program->hIcon)
60           DrawIcon(hdc, 0, 0, program->hIcon);
61         EndPaint(hWnd,&ps);
62         break;
63       }
64     }
65   return(DefWindowProc(hWnd, msg, wParam, lParam));
66 }
67
68 /***********************************************************************
69  *
70  *           PROGRAM_RegisterProgramWinClass
71  */
72
73 ATOM PROGRAM_RegisterProgramWinClass()
74 {
75   WNDCLASS class;
76
77   class.style         = CS_HREDRAW | CS_VREDRAW;
78   class.lpfnWndProc   = PROGRAM_ProgramWndProc;
79   class.cbClsExtra    = 0;
80   class.cbWndExtra    = sizeof(LONG);
81   class.hInstance     = Globals.hInstance;
82   class.hIcon         = 0;
83   class.hCursor       = LoadCursor (0, IDC_ARROW);
84   class.hbrBackground = GetStockObject (WHITE_BRUSH);
85   class.lpszMenuName  = 0;
86   class.lpszClassName = STRING_PROGRAM_WIN_CLASS_NAME;
87
88   return RegisterClass(&class);
89 }
90
91 /***********************************************************************
92  *
93  *           PROGRAM_NewProgram
94  */
95
96 VOID PROGRAM_NewProgram(HLOCAL hGroup)
97 {
98   INT  nCmdShow = SW_SHOWNORMAL;
99   INT  nHotKey = 0;
100   INT  nIconIndex = 0;
101   CHAR szName[MAX_PATHNAME_LEN] = "";
102   CHAR szCmdLine[MAX_PATHNAME_LEN] = "";
103   CHAR szIconFile[MAX_PATHNAME_LEN] = "";
104   CHAR szWorkDir[MAX_PATHNAME_LEN] = "";
105   HICON hIcon = 0;
106
107   if (!DIALOG_ProgramAttributes(szName, szCmdLine, szWorkDir, szIconFile,
108                                 &hIcon, &nIconIndex, &nHotKey,
109                                 &nCmdShow, MAX_PATHNAME_LEN))
110     return;
111
112   if (!hIcon) hIcon = LoadIcon(0, IDI_WINLOGO);
113
114
115   if (!PROGRAM_AddProgram(hGroup, hIcon, szName, 0, 0, szCmdLine, szIconFile,
116                           nIconIndex, szWorkDir, nHotKey, nCmdShow))
117     return;
118
119   GRPFILE_WriteGroupFile(hGroup);
120 }
121
122 /***********************************************************************
123  *
124  *           PROGRAM_ModifyProgram
125  */
126
127 VOID PROGRAM_ModifyProgram(HLOCAL hProgram)
128 {
129   PROGRAM *program = LocalLock(hProgram);
130   CHAR szName[MAX_PATHNAME_LEN];
131   CHAR szCmdLine[MAX_PATHNAME_LEN];
132   CHAR szIconFile[MAX_PATHNAME_LEN];
133   CHAR szWorkDir[MAX_PATHNAME_LEN];
134
135   lstrcpyn(szName, LocalLock(program->hName), MAX_PATHNAME_LEN);
136   lstrcpyn(szCmdLine, LocalLock(program->hCmdLine), MAX_PATHNAME_LEN);
137   lstrcpyn(szIconFile, LocalLock(program->hIconFile), MAX_PATHNAME_LEN);
138   lstrcpyn(szWorkDir, LocalLock(program->hWorkDir), MAX_PATHNAME_LEN);
139
140   if (!DIALOG_ProgramAttributes(szName, szCmdLine, szWorkDir, szIconFile,
141                                 &program->hIcon, &program->nIconIndex,
142                                 &program->nHotKey, &program->nCmdShow,
143                                 MAX_PATHNAME_LEN))
144     return;
145
146   MAIN_ReplaceString(&program->hName, szName);
147   MAIN_ReplaceString(&program->hCmdLine, szCmdLine);
148   MAIN_ReplaceString(&program->hIconFile, szIconFile);
149   MAIN_ReplaceString(&program->hWorkDir, szWorkDir);
150
151   SetWindowText(program->hWnd, szName);
152   UpdateWindow(program->hWnd);
153
154   GRPFILE_WriteGroupFile(program->hGroup);
155
156   return;
157 }
158
159 /***********************************************************************
160  *
161  *           PROGRAM_AddProgram
162  */
163
164 HLOCAL PROGRAM_AddProgram(HLOCAL hGroup, HICON hIcon, LPCSTR lpszName,
165                           INT x, INT y, LPCSTR lpszCmdLine,
166                           LPCSTR lpszIconFile, INT nIconIndex,
167                           LPCSTR lpszWorkDir, INT nHotKey, INT nCmdShow)
168 {
169   PROGGROUP *group = LocalLock(hGroup);
170   PROGRAM *program;
171   HLOCAL hPrior, *p;
172   HLOCAL hProgram  = LocalAlloc(LMEM_FIXED, sizeof(PROGRAM));
173   HLOCAL hName     = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszName));
174   HLOCAL hCmdLine  = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszCmdLine));
175   HLOCAL hIconFile = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszIconFile));
176   HLOCAL hWorkDir  = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszWorkDir));
177   if (!hProgram || !hName || !hCmdLine || !hIconFile || !hWorkDir)
178     {
179       MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK);
180       if (hProgram)  LocalFree(hProgram);
181       if (hName)     LocalFree(hName);
182       if (hCmdLine)  LocalFree(hCmdLine);
183       if (hIconFile) LocalFree(hIconFile);
184       if (hWorkDir)  LocalFree(hWorkDir);
185       return(0);
186     }
187   memcpy(LocalLock(hName),     lpszName,     1 + lstrlen(lpszName));
188   memcpy(LocalLock(hCmdLine),  lpszCmdLine,  1 + lstrlen(lpszCmdLine));
189   memcpy(LocalLock(hIconFile), lpszIconFile, 1 + lstrlen(lpszIconFile));
190   memcpy(LocalLock(hWorkDir),  lpszWorkDir,  1 + lstrlen(lpszWorkDir));
191
192   group->hActiveProgram  = hProgram;
193
194   hPrior = 0;
195   p = &group->hPrograms;
196   while (*p)
197     {
198       hPrior = *p;
199       p = &((PROGRAM*)LocalLock(hPrior))->hNext;
200     }
201   *p = hProgram;
202
203   program = LocalLock(hProgram);
204   program->hGroup     = hGroup;
205   program->hPrior     = hPrior;
206   program->hNext      = 0;
207   program->hName      = hName;
208   program->hCmdLine   = hCmdLine;
209   program->hIconFile  = hIconFile;
210   program->nIconIndex = nIconIndex;
211   program->hWorkDir   = hWorkDir;
212   program->hIcon      = hIcon;
213   program->nCmdShow   = nCmdShow;
214   program->nHotKey    = nHotKey;
215
216   program->hWnd =
217     CreateWindow (STRING_PROGRAM_WIN_CLASS_NAME, lpszName,
218                   WS_CHILD | WS_CAPTION,
219                   x, y, CW_USEDEFAULT, CW_USEDEFAULT,
220                   group->hWnd, 0, Globals.hInstance, 0);
221
222   SetWindowLong(program->hWnd, 0, (LONG) hProgram);
223
224   ShowWindow (program->hWnd, SW_SHOWMINIMIZED);
225   SetWindowPos (program->hWnd, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
226   UpdateWindow (program->hWnd);
227
228   return hProgram;
229 }
230
231 /***********************************************************************
232  *
233  *           PROGRAM_CopyMoveProgram
234  */
235
236 VOID PROGRAM_CopyMoveProgram(HLOCAL hProgram, BOOL bMove)
237 {
238   PROGRAM *program = LocalLock(hProgram);
239   PROGGROUP   *fromgroup = LocalLock(program->hGroup);
240   HLOCAL hGroup = DIALOG_CopyMove(LocalLock(program->hName),
241                                   LocalLock(fromgroup->hName), bMove);
242   if (!hGroup) return;
243
244   /* FIXME shouldn't be necessary */
245   OpenIcon(((PROGGROUP*)LocalLock(hGroup))->hWnd);
246
247   if (!PROGRAM_AddProgram(hGroup,
248 #if 0
249                           CopyIcon(program->hIcon),
250 #else
251                           program->hIcon,
252 #endif
253                           LocalLock(program->hName),
254                           program->x, program->y,
255                           LocalLock(program->hCmdLine),
256                           LocalLock(program->hIconFile),
257                           program->nIconIndex,
258                           LocalLock(program->hWorkDir),
259                           program->nHotKey, program->nCmdShow)) return;
260   GRPFILE_WriteGroupFile(hGroup);
261
262   if (bMove) PROGRAM_DeleteProgram(hProgram, TRUE);
263 }
264
265 /***********************************************************************
266  *
267  *           PROGRAM_ExecuteProgram
268  */
269
270 VOID PROGRAM_ExecuteProgram(HLOCAL hProgram)
271 {
272   PROGRAM *program = LocalLock(hProgram);
273   LPSTR lpszCmdLine = LocalLock(program->hCmdLine);
274   LPSTR lpszWorkDir = LocalLock(program->hWorkDir);
275
276   /* FIXME set working directory */
277   lpszWorkDir = lpszWorkDir;
278
279   WinExec(lpszCmdLine, program->nCmdShow);
280   if (Globals.bMinOnRun) CloseWindow(Globals.hMainWnd);
281 }
282
283 /***********************************************************************
284  *
285  *           PROGRAM_DeleteProgram
286  */
287
288 VOID PROGRAM_DeleteProgram(HLOCAL hProgram, BOOL bUpdateGrpFile)
289 {
290   PROGRAM *program = LocalLock(hProgram);
291   PROGGROUP   *group   = LocalLock(program->hGroup);
292
293   group->hActiveProgram = 0;
294
295   if (program->hPrior)
296     ((PROGRAM*)LocalLock(program->hPrior))->hNext = program->hNext;
297   else
298     ((PROGGROUP*)LocalLock(program->hGroup))->hPrograms = program->hNext;
299
300   if (program->hNext)
301     ((PROGRAM*)LocalLock(program->hNext))->hPrior = program->hPrior;
302
303   if (bUpdateGrpFile)
304     GRPFILE_WriteGroupFile(program->hGroup);
305
306   DestroyWindow(program->hWnd);
307 #if 0
308   if (program->hIcon)
309     DestroyIcon(program->hIcon);
310 #endif
311   LocalFree(program->hName);
312   LocalFree(program->hCmdLine);
313   LocalFree(program->hIconFile);
314   LocalFree(program->hWorkDir);
315   LocalFree(hProgram);
316 }
317
318 /***********************************************************************
319  *
320  *           PROGRAM_FirstProgram
321  */
322
323 HLOCAL PROGRAM_FirstProgram(HLOCAL hGroup)
324 {
325   PROGGROUP *group;
326   if (!hGroup) return(0);
327   group = LocalLock(hGroup);
328   return(group->hPrograms);
329 }
330
331 /***********************************************************************
332  *
333  *           PROGRAM_NextProgram
334  */
335
336 HLOCAL PROGRAM_NextProgram(HLOCAL hProgram)
337 {
338   PROGRAM *program;
339   if (!hProgram) return(0);
340   program = LocalLock(hProgram);
341   return(program->hNext);
342 }
343
344 /***********************************************************************
345  *
346  *           PROGRAM_ActiveProgram
347  */
348
349 HLOCAL PROGRAM_ActiveProgram(HLOCAL hGroup)
350 {
351   PROGGROUP *group;
352   if (!hGroup) return(0);
353   group = LocalLock(hGroup);
354   if (IsIconic(group->hWnd)) return(0);
355
356   return(group->hActiveProgram);
357 }
358
359 /***********************************************************************
360  *
361  *           PROGRAM_ProgramName
362  */
363
364 LPCSTR PROGRAM_ProgramName(HLOCAL hProgram)
365 {
366   PROGRAM *program;
367   if (!hProgram) return(0);
368   program = LocalLock(hProgram);
369   return(LocalLock(program->hName));
370 }
371
372 /* Local Variables:    */
373 /* c-file-style: "GNU" */
374 /* End:                */