|
|
1.1 root 1:
2: /******************************************************************************\
3: * This is a part of the Microsoft Source Code Samples.
4: * Copyright (C) 1993 Microsoft Corporation.
5: * All rights reserved.
6: * This source code is only intended as a supplement to
7: * Microsoft Development Tools and/or WinHelp documentation.
8: * See these sources for detailed information regarding the
9: * Microsoft samples programs.
10: \******************************************************************************/
11:
12: /*
13: ddeprocs.c
14: */
15:
16: #include <windows.h>
17: #include <stdlib.h>
18: #include <stdio.h>
19: #include "ddeinst.h"
20: #include "ddextrn.h"
21: #include "dialogs.h"
22:
23: // function prototype for List synchronization
24: void SynchronizeLists (HWND);
25: void SynchronizeListSelection (HWND);
26:
27: // function prototype for child window creation
28: void CreateChildren (HWND);
29:
30: // internal thread counter
31: int iThreadCount = 0;
32:
33: /********************************************************************
34:
35: MainWndProc.
36:
37: Function that processes the messages sent to the main window.
38:
39: ********************************************************************/
40:
41: LRESULT APIENTRY MainWndProc (HWND hwnd, UINT uiMsg, WPARAM wParam,
42: LPARAM lParam) {
43: BOOL fFlag;
44:
45: switch (uiMsg) {
46: case WM_CREATE: {
47:
48: // Create all of the child windows that are desired.
49: CreateChildren (hwnd);
50: break;
51: }/*endCase*/
52: case WM_DESTROY: {
53: PostQuitMessage (0);
54: return (0L);
55: }/*endCase*/
56: case WM_USER_CLOSE_DIALOG: {
57: if (hwndDialog) {
58: DestroyWindow (hwndDialog);
59: hwndDialog = (HWND) NULL;
60: return (TRUE);
61: }/*endIf*/
62: break;
63: }/*endCase*/
64: case WM_SIZE: {
65: /* Need to resize the StatusBar */
66: if (hwndStatus) {
67: long lHeight;
68: int iWidth;
69: int iHeight;
70:
71: iWidth = LOWORD (lParam);
72: iHeight = HIWORD (lParam);
73: lHeight = GetWindowLong (hwndStatus, GWL_USERDATA);
74: MoveWindow (hwndStatus, -1, iHeight - (int) lHeight,
75: iWidth + 2, lHeight + 2, TRUE);
76: }/*endIf*/
77: break;
78: }/*endCase*/
79: case WM_USER_GET_APPS: {
80: StartTraverseThread (szUserPath);
81: return (1L);
82: }/*endCase*/
83: case WM_USER_GET_GROUPS: {
84: StartGroupRetrievalThread ();
85: return (1L);
86: }/*endCase*/
87: case WM_USER_THREAD_DONE: {
88: iThreadCount++;
89: if (!fBatch) {
90: break;
91: }/*endIf*/
92: if (iThreadCount == 2) {
93: PostMessage (ghwndMain, WM_COMMAND,
94: (WPARAM) MAKELONG (ID_ADDALLBUTTON, BN_CLICKED),
95: (LPARAM) hwndAddAll);
96: PostMessage (ghwndMain, WM_COMMAND,
97: (WPARAM) MAKELONG (ID_ADDGROUP, BN_CLICKED),
98: (LPARAM) hwndAddGroupButton);
99: PostMessage (ghwndMain, WM_COMMAND,
100: (WPARAM) MAKELONG (ID_ADDBUTTON, BN_CLICKED),
101: (LPARAM) hwndAddButton);
102: iThreadCount = 0;
103: }/*endIf*/
104: break;
105: }/*endCase*/
106: case WM_COMMAND: {
107: switch (HIWORD (wParam)) {
108: case LBN_SELCHANGE: {
109: SynchronizeListSelection ((HWND) lParam);
110: if ((HWND) lParam == hwndCombo) {
111: EnableWindow (hwndAddGroupButton, TRUE);
112: }/*endIf*/
113: break;
114: }/*endCase*/
115: case CBN_EDITCHANGE: {
116: fFlag = (BOOL) GetWindowTextLength (hwndCombo);
117: EnableWindow (hwndAddGroupButton, fFlag);
118: break;
119: }/*endCase*/
120: case BN_CLICKED: {
121: switch (LOWORD (wParam)) {
122: case ID_ADDALLBUTTON: {
123:
124: // Select all elements in the two lists.
125: // Under Win 3.x LPARAM of LB_SETSEL is MAKELPARAM (-1, 0)
126: // Under Win32 it is -1
127:
128: SendMessage (hwndFileList, LB_SETSEL, (WPARAM) TRUE,
129: (LPARAM) -1);
130:
131: // Under Win 3.x LPARAM of LB_SETSEL is MAKELPARAM (-1, 0)
132: // Under Win32 it is -1
133:
134: SendMessage (hwndFileList2, LB_SETSEL, (WPARAM) TRUE,
135: (LPARAM) -1);
136: break;
137: }/*endCase*/
138: case ID_EXITBUTTON: {
139: PostQuitMessage (0);
140: break;
141: }/*endCase*/
142: case ID_ADDBUTTON: {
143: // Create the Progress Dialog
144: hwndDialog = CreateDialog (ghModule,
145: "ProgressDialog", hwnd, ProgressDlgWndProc);
146:
147: // Start a thread to add the items
148: StartAddThread ();
149: break;
150: }/*endCase*/
151: case ID_ADDGROUP: {
152:
153: // Add the user defined group.
154: CreateGroup ();
155: break;
156: }/*endCase*/
157: }/*endSwitch*/
158: break;
159: }/*endCase*/
160: }/*endSwitch*/
161:
162: // Process menu events now.
163:
164: switch (LOWORD (wParam)) {
165: case DI_EXIT: {
166: PostQuitMessage (0);
167: return (1L);
168: }/*endCase*/
169: case DI_ABOUT: {
170: DialogBox (ghModule, "AboutBox", hwnd,
171: (DLGPROC) AboutBoxWndProc);
172: break;
173: }/*endCase*/
174: }/*endSwitch*/
175: break;
176: }/*endCase*/
177: }/*endSwitch*/
178: return (DefWindowProc (hwnd, uiMsg, wParam, lParam));
179: }/* end MainWndProc */
180:
181: /********************************************************************
182:
183: StatusBarWndProc.
184:
185: Function that manages the Status bar at the bottom of the main
186: window.
187:
188: ********************************************************************/
189:
190: LRESULT APIENTRY StatusBarWndProc (HWND hwnd, UINT uiMsg, WPARAM wParam,
191: LPARAM lParam) {
192: HDC hdc;
193: long lHeight;
194: RECT rc;
195: PAINTSTRUCT ps;
196: TEXTMETRIC tm;
197: POINT pts[6];
198:
199: switch (uiMsg) {
200: case WM_CTLCOLORSTATIC: {
201: SetBkMode ((HDC) wParam, TRANSPARENT);
202: return ((LRESULT) GetStockObject (WHITE_BRUSH));
203: }/*endCase*/
204: case WM_CREATE: {
205: hdc = GetDC (hwnd); // Get the DC for text metrics
206:
207: GetClientRect (GetParent (hwnd), &rc);
208: GetTextMetrics (hdc, &tm);
209:
210: // Calculate the height of the window
211: lHeight = tm.tmHeight + 10 * GetSystemMetrics (SM_CYBORDER) + 2;
212:
213: // Save away the calculated height
214: SetWindowLong (hwnd, GWL_USERDATA, lHeight);
215:
216: //* resize the window
217: SetWindowPos (hwnd, NULL, -1, rc.bottom - lHeight,
218: rc.right + 2, lHeight + 2, SWP_NOZORDER | SWP_NOMOVE);
219:
220: ReleaseDC (hwnd, hdc);
221: break;
222: }/*endCase*/
223: case WM_USER_UPDATE_STATUS: {
224: switch (lParam) {
225: case ID_DDEML_CONNECT: {
226: SetWindowText (hwndStatusText, "DDEML Connection");
227: break;
228: }/*endCase*/
229: case ID_DDEML_RETRIEVING: {
230: SetWindowText (hwndStatusText, "DDEML Retrieving");
231: break;
232: }/*endCase*/
233: case ID_DDEML_DISCONNECT: {
234: SetWindowText (hwndStatusText, "DDEML Disconnect");
235: break;
236: }/*endCase*/
237: case ID_DDEML_COMPLETE: {
238: SetWindowText (hwndStatusText, "DDEML Complete");
239: break;
240: }/*endCase*/
241: case ID_DDEML_ACTIVATE: {
242: SetWindowText (hwndStatusText, "DDEML Activate Group");
243: break;
244: }/*endCase*/
245: case ID_DDEML_CREATE: {
246: SetWindowText (hwndStatusText, "DDEML Create Group");
247: break;
248: }/*endCase*/
249: case ID_DDEML_ADD: {
250: TCHAR szText[32];
251:
252: sprintf (szText, "DDEML Add Item %ld", wParam);
253: SetWindowText (hwndStatusText, szText);
254: break;
255: }/*endCase*/
256: }/*endSwitch*/
257: break;
258: }/*endCase*/
259: case WM_PAINT: {
260: HBRUSH hBrush;
261: HBRUSH hBrushTemp;
262: HPEN hPen;
263: HPEN hPenTemp;
264:
265: hdc = BeginPaint (hwnd, &ps);
266: GetClientRect (hwnd, &rc);
267:
268: lHeight = GetWindowLong (hwnd, GWL_USERDATA);
269: pts[0].x = 3;
270: pts[0].y = pts[5].y = lHeight - 4;
271: pts[1].x = 6;
272: pts[1].y = pts[2].y = lHeight - 6;
273: pts[2].x = pts[3].x = (rc.right / 2) - 4;
274: pts[3].y = 6;
275: pts[4].y = 3;
276: pts[4].x = pts[5].x = rc.right / 2;
277: hBrush = GetStockObject (WHITE_BRUSH);
278: hPen = GetStockObject (WHITE_PEN);
279: hBrushTemp = SelectObject (hdc, hBrush);
280: hPenTemp = SelectObject (hdc, hPen);
281: SetPolyFillMode (hdc, WINDING);
282: Polygon (hdc, pts, 6);
283: hBrush = CreateSolidBrush (GetSysColor (COLOR_BTNSHADOW));
284: pts[2].x = 6;
285: hPen = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_BTNSHADOW));
286: pts[2].y = 6;
287: pts[5].x = pts[5].y = 3;
288: SelectObject (hdc, hBrush);
289: SelectObject (hdc, hPen);
290: Polygon (hdc, pts, 6);
291: rc.left = rc.top = 7;
292: rc.right = (rc.right / 2) - 4;
293: rc.bottom = lHeight - 7;
294: SelectObject (hdc, hBrushTemp);
295: SelectObject (hdc, hPenTemp);
296: DeleteObject (hBrush);
297: DeleteObject (hPen);
298: hBrush = GetStockObject (WHITE_BRUSH);
299: FillRect (hdc, &rc, hBrush);
300: DeleteObject (hBrush);
301: EndPaint (hwnd, &ps);
302: return (0L);
303: }/*endCase*/
304: }/*endSwitch*/
305: return (DefWindowProc (hwnd, uiMsg, wParam, lParam));
306: }/* end StatusBarWndProc */
307:
308: /********************************************************************
309:
310: ListBoxWndProc.
311:
312: Function that manages the list boxes that are on the screen. Subclassed
313: to provide additional functionality.
314:
315: ********************************************************************/
316:
317: LRESULT APIENTRY ListBoxWndProc (HWND hwnd, UINT uiMsg, WPARAM wParam,
318: LRESULT lParam) {
319:
320: switch (uiMsg) {
321: case WM_KEYUP: {
322: SynchronizeLists (hwnd);
323: break;
324: }/*endCase*/
325: case WM_VSCROLL: {
326: SynchronizeLists (hwnd);
327: break;
328: }/*endCase*/
329: break;
330: }/*endSwitch*/
331: return (CallWindowProc (DefListBoxWndProc, hwnd, uiMsg, wParam, lParam));
332: }/* end ListBoxWndProc */
333:
334: /********************************************************************
335:
336: SynchronizeLists.
337:
338: Function that makes sure that the two lists are synchronized and
339: always have the same selection.
340:
341: ********************************************************************/
342:
343: void SynchronizeLists (HWND hwnd) {
344: HWND hwndOther;
345: long lSourceTop;
346: long lTargetTop;
347:
348: // If this is from the combo list then return.
349: if (hwnd == hwndCombo) {
350: return;
351: }/*endIf*/
352:
353: // Figure out which list caused the event and update the other.
354: if (hwnd == hwndFileList) {
355: hwndOther = hwndFileList2;
356: } else {
357: hwndOther = hwndFileList;
358: }/*endIf*/
359:
360: // Get the top index of the source list.
361: lSourceTop = SendMessage (hwnd, LB_GETTOPINDEX, 0, 0L);
362:
363: // Get the top index of the target list.
364: lTargetTop = SendMessage (hwndOther, LB_GETTOPINDEX, 0, 0L);
365:
366: // If the top indexes are different set the top of the target to the
367: // same value as the source.
368: if (lSourceTop != lTargetTop) {
369: SendMessage (hwndOther, LB_SETTOPINDEX, lSourceTop, 0L);
370: }/*endIf*/
371: }/* end SynchronizeLists */
372:
373: /********************************************************************
374:
375: SynchronizeListSelection.
376:
377: Function that actually manages the list selection.
378:
379: ********************************************************************/
380:
381: void SynchronizeListSelection (HWND hwnd) {
382: HWND hwndOther;
383: long lNumSel;
384: int * lpSelection;
385: long lIndex;
386:
387: // If this is from the combo list then return.
388:
389: if (hwnd == hwndCombo) {
390: return;
391: }/*endIf*/
392:
393: // Figure out which list caused the event and update the other.
394:
395: if (hwnd == hwndFileList) {
396: hwndOther = hwndFileList2;
397: } else {
398: hwndOther = hwndFileList;
399: }/*endIf*/
400:
401: // Find out how many items are selected in the source list.
402:
403: lNumSel = SendMessage (hwnd, LB_GETSELCOUNT, 0, 0L);
404: if (lNumSel != LB_ERR && lNumSel != 0) {
405:
406: // Allocate a block of memory to hold the selection indexes.
407: lpSelection = (int *) GlobalAlloc (GMEM_FIXED | GMEM_ZEROINIT,
408: lNumSel * sizeof (int));
409: if (lpSelection) {
410:
411: // Clear the selection in the list before reselecting.
412: // Under Win 3.x LPARAM of LB_SETSEL is MAKELPARAM (-1, 0)
413: // Under Win32 it is -1
414:
415: SendMessage (hwndOther, LB_SETSEL, (WPARAM) FALSE, (LPARAM) -1);
416:
417: // Retrieve the selection indexes.
418:
419: SendMessage (hwnd, LB_GETSELITEMS, lNumSel, (LPARAM) lpSelection);
420:
421: // Loop the indexes selecting the same values in the target list.
422:
423: for (lIndex = 0; lIndex < lNumSel; lIndex++) {
424: SendMessage (hwndOther, LB_SETSEL, (WPARAM) TRUE,
425: MAKELPARAM (lpSelection[lIndex], 0));
426: }/*endFor*/
427:
428: // Release the memory that was allocated.
429:
430: GlobalFree (lpSelection);
431: }/*endIf*/
432: }/*endIf*/
433: }/* end SynchronizeListSelection */
434:
435: /********************************************************************
436:
437: CreateChildren.
438:
439: Function that creates all of the child windows for the app.
440:
441: ********************************************************************/
442:
443: void CreateChildren (HWND hwnd) {
444: int iListHeight;
445: long lHeight;
446: RECT rc;
447:
448: // Create the status bar at the bottom of the window.
449: hwndStatus = CreateWindow ("StatusBar", NULL,
450: WS_BORDER | SS_LEFT | WS_CHILD | WS_VISIBLE,
451: 0, 0, 0, 0, hwnd, (HMENU) ID_STATUSBAR, ghModule, NULL);
452:
453: // Retrieve the height of the status bar.
454: lHeight = GetWindowLong (hwndStatus, GWL_USERDATA);
455:
456: // Retrieve the size of the client area of the status bar.
457: GetClientRect (hwndStatus, &rc);
458:
459: hwndStatusText = CreateWindow ("Static", "Status Bar",
460: WS_VISIBLE | WS_CHILD | SS_LEFT,
461: 7, 7, rc.right / 2 - 10, lHeight - 14, hwndStatus, (HMENU) 0, ghModule,
462: NULL);
463:
464: // Retrieve the size of the client area of the parent window
465: GetClientRect (hwnd, &rc);
466:
467: // Calculate the size of a list box.
468: iListHeight = rc.bottom - lHeight * 2;
469:
470: // Decrease the size of lHeight to compensate for size of status bar.
471: lHeight -= 8;
472:
473: // Create a Static window in the upper left corner.
474: CreateWindow ("Static", "Available exe's",
475: WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | SS_LEFT,
476: 0, 0, 200, lHeight - 2, hwnd, (HMENU) 0, ghModule, NULL);
477:
478: // Create the first list to hold the file name.
479: hwndFileList = CreateWindow ("ListBox", NULL, WS_CLIPSIBLINGS | LBS_NOTIFY |
480: WS_BORDER | WS_VISIBLE | WS_CHILD | LBS_EXTENDEDSEL | LBS_HASSTRINGS,
481: 0, lHeight, 150, iListHeight, hwnd, (HMENU) ID_FILELIST, ghModule,
482: NULL);
483:
484: // Subclass the list box window proc so we can do the synchronization
485: DefListBoxWndProc = (WNDPROC) GetWindowLong (hwndFileList, GWL_WNDPROC);
486: SetWindowLong (hwndFileList, GWL_WNDPROC, (LONG) ListBoxWndProc);
487:
488: // Create the second list box that holds the name that will be used in the
489: // Program Manager.
490: hwndFileList2 = CreateWindow ("ListBox", NULL,
491: WS_BORDER | WS_VISIBLE | WS_CHILD | WS_VSCROLL | LBS_EXTENDEDSEL |
492: LBS_NOTIFY | LBS_HASSTRINGS | LBS_SORT | WS_CLIPSIBLINGS, 150,
493: lHeight, 150, iListHeight, hwnd, (HMENU) ID_FILELIST2, ghModule,
494: NULL);
495:
496: // Subclass the list.
497: SetWindowLong (hwndFileList2, GWL_WNDPROC, (LONG) ListBoxWndProc);
498:
499: // Create a third list box that is not visible that contains the absolute
500: // path to the executable.
501: hwndPathList = CreateWindow ("ListBox", NULL,
502: WS_BORDER | WS_CHILD | WS_VSCROLL | LBS_EXTENDEDSEL |
503: LBS_NOTIFY | LBS_HASSTRINGS | LBS_SORT | WS_CLIPSIBLINGS, 150, lHeight,
504: 150, iListHeight, hwnd, (HMENU) ID_PATHLIST, ghModule, NULL);
505:
506: // Create a button that is used to add a group.
507: hwndAddGroupButton = CreateWindow ("Button", "Add Group",
508: WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
509: rc.right - 110, iListHeight - (int) (lHeight * 4),
510: 100, lHeight, hwnd, (HMENU) ID_ADDGROUP, ghModule, NULL);
511:
512: // Create the button that is used to add the selected items.
513: hwndAddButton = CreateWindow ("Button", "Add Items",
514: WS_DISABLED | WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
515: rc.right - 110, iListHeight - (int) (lHeight * 3),
516: 100, lHeight, hwnd, (HMENU) ID_ADDBUTTON, ghModule, NULL);
517:
518: // Create the button that is used to select all of the items in the list.
519: hwndAddAll = CreateWindow ("Button", "Select All",
520: WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
521: rc.right - 110, iListHeight - (int) (lHeight * 2),
522: 100, lHeight, hwnd, (HMENU) ID_ADDALLBUTTON, ghModule, NULL);
523:
524: // Create a button that can be used to exit the application.
525: hwndExitButton = CreateWindow ("Button", "Exit",
526: WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
527: rc.right - 110, iListHeight - (int) lHeight, 100, lHeight, hwnd,
528: (HMENU) ID_EXITBUTTON, ghModule, NULL);
529:
530: // Create a drop down combo box for the group names from the Program Manager.
531: hwndCombo = CreateWindow ("ComboBox", NULL,
532: WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | CBS_DROPDOWN | WS_VSCROLL |
533: CBS_AUTOHSCROLL | CBS_HASSTRINGS, rc.right - 200, lHeight,
534: 190, lHeight * 5, hwnd, (HMENU) ID_COMBOBOX, ghModule, NULL);
535:
536: // Create a Static window to label the combo box.
537: CreateWindow ("Static", "Available Groups",
538: WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | SS_LEFT,
539: rc.right - 200, 0, 190, lHeight - 2, hwnd, (HMENU) 0, ghModule, NULL);
540: }/* end CreateChildren */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.