|
|
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.