home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / security / crypto / cfiler / drvproc.c < prev    next >
C/C++ Source or Header  |  1997-10-08  |  34KB  |  1,036 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright 1996-1997 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. // DRVPROC.C
  13.  
  14. #include "cfiler.h"
  15.  
  16. extern HANDLE               ghModule;
  17. extern HANDLE                ghwndMain;
  18. extern HFONT                ghFont;
  19. extern HANDLE               ghDrvThread;
  20. extern HANDLE               ghMenu;
  21. extern HWND                     ghwndDrives;
  22. extern HWND                   ghwndDrv;
  23. extern HWND                 ghFocusWnd;
  24. extern LPDINFO              glpDrives;
  25. extern CRITICAL_SECTION        gDrvCS;   
  26.  
  27. /**********************************************************************\
  28. * DrawItem()
  29. *
  30. * in parmeters
  31. * lpdis - Information the owner window must have to determine how 
  32. * to paint the owner-draw listbox
  33. *
  34. * Calls DrawText to output a string with the right color in the
  35. * rectangle contained in lpdis
  36. \**********************************************************************/
  37.  
  38. VOID APIENTRY DrawItem(LPDRAWITEMSTRUCT lpdis) {
  39.         COLORREF crOldColor;
  40.         TCHAR    szFile[256];
  41.         INT     i, nLen;
  42.         TCHAR szBuf[275];
  43.         TEXTMETRIC tm;
  44.         RECT rc;
  45.  
  46.         if (!lpdis) {
  47.             ErrorMsg(TEXT("DrawEntireItem: lpdis is NULL."));
  48.             return;
  49.         }
  50.         
  51.         GetTextMetrics(lpdis->hDC, &tm);
  52.         
  53.           // Filenames such as Q&A.DOC should look correct.
  54.           
  55.           ReplaceEscapeCharacters((LPTSTR)lpdis->itemData, szBuf);
  56.                 
  57.         nLen = lstrlen(szBuf);
  58.         
  59.         if (nLen > HEADER_SIZE) {
  60.             ErrorMsg(TEXT("fnKey has been Destroyed!"));
  61.             crOldColor = SetTextColor(lpdis->hDC, RGB(140, 140, 140));
  62.             CopyRect(&rc, &lpdis->rcItem);
  63.                rc.left += 1;
  64.                lstrcpy(szFile, TEXT("RecoverMe"));
  65.                DrawText(lpdis->hDC, szFile, lstrlen(szFile), (LPRECT)&rc, DT_LEFT);
  66.               SetTextColor(lpdis->hDC, crOldColor);
  67.             return;
  68.         }
  69.         
  70.         if (szBuf[0] == TEXT('|')) {
  71.             
  72.             // This is an encrypted file. Select gray as the color.
  73.             
  74.             crOldColor = SetTextColor(lpdis->hDC, RGB(140, 140, 140));
  75.             
  76.             for (i = 0; i < nLen - 1; i++)
  77.                 szFile[i] = szBuf[i + 1];
  78.  
  79.             szFile[i] = TEXT('\0');
  80.         }
  81.         else if (szBuf[0] == TEXT('>')) {
  82.             
  83.             // This is an encrypted and signed file.
  84.             
  85.             crOldColor = SetTextColor(lpdis->hDC, RGB(255, 140, 140));
  86.             
  87.             for (i = 0; i < nLen - 1; i++)
  88.                 szFile[i] = szBuf[i + 1];
  89.  
  90.             szFile[i] = TEXT('\0');
  91.         }
  92.         else if (szBuf[0] == TEXT(';')) {
  93.             
  94.             // This is a signed only file.
  95.             
  96.             crOldColor = SetTextColor(lpdis->hDC, RGB(255, 0, 0));
  97.             
  98.             for (i = 0; i < nLen - 1; i++)
  99.                 szFile[i] = szBuf[i + 1];
  100.  
  101.             szFile[i] = TEXT('\0');
  102.         }
  103.         else 
  104.             lstrcpy(szFile, szBuf);
  105.                   
  106.            CopyRect(&rc, &lpdis->rcItem);
  107.            
  108.            rc.left += 1;
  109.            
  110.            DrawText(lpdis->hDC, szFile, lstrlen(szFile), (LPRECT)&rc, DT_LEFT);
  111.          
  112.         if (szBuf[0] == TEXT('|') || szBuf[0] == TEXT('>') || szBuf[0] == TEXT(';'))
  113.                SetTextColor(lpdis->hDC, crOldColor);
  114.         
  115.            return;
  116. }
  117.  
  118. /**********************************************************************\
  119. * HandleSelectionState()
  120. *
  121. * in parmeters
  122. * lpdis - Information the owner window must have to determine how 
  123. * to paint the owner-draw listbox
  124. *
  125. * purpose:
  126. * Handles a change in an item selection state. This function must
  127. * check the current background color for the rectangle contained
  128. * in the DRAWITEMSTRUCT pointer, lpdis. The background color and
  129. * text color must be changed appropriately.
  130. \**********************************************************************/
  131.  
  132. VOID APIENTRY HandleSelectionState(LPDRAWITEMSTRUCT lpdis)
  133. {
  134.      if (!lpdis) {
  135.          ErrorMsg(TEXT("HandleSelectionState: lpdis is NULL."));
  136.          return;
  137.      }
  138.      
  139.      if (lpdis->itemState & ODS_SELECTED) {
  140.          if (GetBkColor(lpdis->hDC) == GetSysColor(COLOR_HIGHLIGHT)) {
  141.             return;
  142.         }
  143.         else {
  144.             SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  145.             SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
  146.             DrawItem(lpdis);
  147.             return;
  148.         }
  149.     }
  150.     else {
  151.         if (GetBkColor(lpdis->hDC) != GetSysColor(COLOR_WINDOW)) {
  152.             return;
  153.         }
  154.         else {
  155.             SetTextColor(lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
  156.             SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW));
  157.             DrawItem(lpdis);
  158.             return;
  159.         }
  160.     }
  161. }
  162.  
  163. /**********************************************************************\
  164. * DrawEntireItem()
  165. *
  166. * in parmeters
  167. * lpdis - Information the owner window must have to determine how 
  168. * to paint the owner-draw listbox
  169. *
  170. * Sets the background color and the text color and calls DrawItem()
  171. \**********************************************************************/
  172.  
  173. VOID APIENTRY DrawEntireItem(LPDRAWITEMSTRUCT lpdis)
  174. {
  175.         if (!lpdis) {
  176.             ErrorMsg(TEXT("DrawEntireItem: lpdis is NULL."));
  177.             return;
  178.         }
  179.         
  180.         SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW));
  181.         SetTextColor(lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
  182.  
  183.         DrawItem(lpdis);
  184.          
  185.         __try {
  186.             if (!lpdis) {
  187.                 ErrorMsg(TEXT("DrawEntireItem: lpdis is NULL."));
  188.                 return;
  189.             }
  190.             
  191.             if (!lpdis->itemData) {
  192.                 ErrorMsg(TEXT("DrawEntireItem: lpdis->itemData is NULL."));
  193.                 return;
  194.             }
  195.         }
  196.         __except (EXCEPTION_EXECUTE_HANDLER) {
  197.             ErrorMsg(TEXT("DrawEntireItem: lpdis is BOGUS."));
  198.             return;
  199.         }
  200.         
  201.         /* Draw or erase appropriate frames */
  202.         __try {
  203.             HandleSelectionState(lpdis);
  204.         }
  205.         __except (EXCEPTION_EXECUTE_HANDLER) {
  206.             ErrorMsg(TEXT("DrawEntireItem: Attempt to call HandleSelectionState raised an exception."));
  207.             return;
  208.         }
  209. }
  210.  
  211. LRESULT  WINAPI DrvWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  212.     LPDRAWITEMSTRUCT lpdis;
  213.     LPMEASUREITEMSTRUCT lpmis;
  214.     LPCOMPAREITEMSTRUCT lpcis;
  215.     
  216.     DWORD dwDirStyle = WS_BORDER | WS_CHILD | WS_VISIBLE |
  217.                               LBS_NOINTEGRALHEIGHT | LBS_NOTIFY |
  218.                               LBS_HASSTRINGS | LBS_WANTKEYBOARDINPUT |
  219.                               LBS_DISABLENOSCROLL | WS_HSCROLL |
  220.                               WS_VSCROLL |LBS_USETABSTOPS;
  221.  
  222.     DWORD dwFileStyle = WS_BORDER | WS_CHILD | WS_VISIBLE |
  223.                               LBS_NOINTEGRALHEIGHT | LBS_NOTIFY |
  224.                                  LBS_OWNERDRAWFIXED | LBS_WANTKEYBOARDINPUT |
  225.                               LBS_DISABLENOSCROLL | WS_HSCROLL |
  226.                               LBS_EXTENDEDSEL | LBS_MULTIPLESEL |
  227.                               LBS_MULTICOLUMN | LBS_SORT;
  228.  
  229.     switch (message){
  230.  
  231.         //
  232.         // Creates the text and listbox windows for this Drv child and
  233.         //  saves its handle in the per Drv child DRVCHILDINFO data structure.
  234.         //
  235.         case WM_CREATE: {
  236.             LPCINFO lpCInfo;
  237.  
  238.             DWORD   dwLoop;
  239.  
  240.             LPDINFO lpWalk;
  241.  
  242.             LONG    lTabs = LISTBOX_TAB_SIZE;
  243.             
  244.             //
  245.             // Initialize DRVCHILDINFO structure
  246.             //
  247.             lpCInfo = (LPCINFO) ((LPCREATESTRUCT) lParam)->lpCreateParams;
  248.  
  249.             if (!lpCInfo) {
  250.                 ErrorMsg(TEXT("DrvWndProc: lpCInfo is NULL."));
  251.                 return 0;
  252.              }
  253.              
  254.              lpCInfo->hwnd = hwnd;
  255.  
  256.             // Create text window
  257.             lpCInfo->hTextWnd = CreateWindow(TEXT("TextClass"), NULL,
  258.                                        SS_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER,
  259.                                     0, 0, 0, 0,
  260.                                     lpCInfo->hwnd,
  261.                                     (HMENU) TEXT_WINDOW_ID,
  262.                                     ghModule,
  263.                                     NULL);
  264.  
  265.             if (!lpCInfo->hTextWnd) {
  266.                 ErrorMsg(TEXT("DrvWndProc: WM_CREATE: CreateWindow failed."));
  267.                 return 0;
  268.             }
  269.             
  270.             // Create Directory and File List boxes
  271.             lpCInfo->hDirLB = CreateWindow(TEXT("LISTBOX"), NULL,
  272.                                     dwDirStyle,
  273.                                     0, 0, 0, 0,
  274.                                     lpCInfo->hwnd,
  275.                                     (HMENU) LISTDIR_ID,
  276.                                     ghModule,
  277.                                     NULL);
  278.  
  279.             if (!lpCInfo->hDirLB) {
  280.                 ErrorMsg(TEXT("DrvWndProc: WM_CREATE: CreateWindow failed."));
  281.                 return 0;
  282.             }
  283.             
  284.             // Create directory listbox string table.
  285.             
  286.             lpCInfo->DirTable = TableNew();
  287.  
  288.             if (!lpCInfo->DirTable) {
  289.                 ErrorMsg(TEXT("WM_CREATE: TableNew failed."));
  290.                 return 0;
  291.             }
  292.             
  293.             lpCInfo->hFileLB = CreateWindow(TEXT("LISTBOX"), NULL,
  294.                                     dwFileStyle,
  295.                                     0, 0, 0, 0,
  296.                                     lpCInfo->hwnd,
  297.                                     (HMENU) LISTFILE_ID,
  298.                                     ghModule,
  299.                                     NULL);
  300.             
  301.             if (!lpCInfo->hFileLB) {
  302.                 ErrorMsg(TEXT("DrvWndProc: WM_CREATE: CreateWindow failed."));
  303.                 return 0;
  304.             }
  305.             
  306.             lpCInfo->FileTable = TableNew();
  307.             
  308.             if (!lpCInfo->FileTable) {
  309.                 ErrorMsg(TEXT("WM_CREATE: TableNew failed."));
  310.                 return 0;
  311.             }
  312.             
  313.             if (!Logon(hwnd)) {
  314.                 MessageBox(hwnd, TEXT("DrvWndProc: WM_CREATE: Logon failed. Terminating application."), NULL, MB_OK);
  315.                 exit(1);
  316.                 return 0;
  317.             }
  318.         
  319.             //
  320.             // fDirLeft indicates whether the Directory ListBox defaults to
  321.             //  the left side of each of the two drive windows.
  322.             // fDirExpand indicates whether the Directory Listbox defaults
  323.             //  to full expansion.
  324.             //
  325.             lpCInfo->fDirLeft = TRUE;
  326.             lpCInfo->fDirExpand = FALSE;
  327.             lpCInfo->fSuicide = FALSE;
  328.  
  329.             //
  330.             // Create Mutex associated with each list box
  331.             //
  332.             lpCInfo->hDirMutex = CreateMutex(NULL, FALSE, NULL);
  333.             lpCInfo->hFileMutex = CreateMutex(NULL, FALSE, NULL);
  334.  
  335.             //
  336.             // Associate window with the current directory LPDINFO structure
  337.             //   from the Drives linked list
  338.             //
  339.                             
  340.             dwLoop = GetCurrentDirectory( DIRECTORY_STRING_SIZE,
  341.                                           lpCInfo->CaptionBarText);
  342.             
  343.             CharUpper(lpCInfo->CaptionBarText);
  344.  
  345.             WaitForSingleObject(ghDrvThread, INFINITE);
  346.             EnterCriticalSection(&gDrvCS);
  347.  
  348.             lpWalk = glpDrives;
  349.  
  350.             if(dwLoop && dwLoop <= DIRECTORY_STRING_SIZE) {
  351.                 while(lpWalk && tolower(lpWalk->DriveName[0]) 
  352.                                 != tolower((lpCInfo->CaptionBarText)[0]))
  353.                     lpWalk = lpWalk->next;
  354.  
  355.                 if( !lpWalk ){
  356.                     ErrorMsg(TEXT("Drive Child Create: Drive list failure."));
  357.                     LeaveCriticalSection(&gDrvCS);
  358.                     return(-1);
  359.                 }
  360.             }
  361.             else{
  362.                 ErrorMsg(TEXT("Drive Child Create: GetCurrentDir failure."));
  363.                 LeaveCriticalSection(&gDrvCS);
  364.                 return(-1);
  365.             }
  366.  
  367.             LeaveCriticalSection(&gDrvCS);
  368.  
  369.             lpCInfo->lpDriveInfo = lpWalk;
  370.  
  371.             //
  372.             // Save the handle to DRVCHILDINFO in our window structure
  373.             //
  374.             SetWindowLong(hwnd, GWL_USERDATA, (LONG) lpCInfo);
  375.  
  376.             //
  377.             // Initialize child windows
  378.             //
  379.             if( !SendMessage(lpCInfo->hDirLB, LB_SETTABSTOPS, (WPARAM)1,
  380.                             (LPARAM)&lTabs) )
  381.                 ErrorMsg(TEXT("Drv window Create: Set tab stop failure."));
  382.  
  383.  
  384.             //
  385.             // Set default font.
  386.             //
  387.             SendMessage(lpCInfo->hDirLB, WM_SETFONT, (WPARAM)ghFont, (LPARAM)FALSE);
  388.             SendMessage(lpCInfo->hFileLB, WM_SETFONT, (WPARAM)ghFont, (LPARAM)FALSE);
  389.  
  390.             SendMessage(hwnd, WM_COMMAND, (WPARAM)MM_REFRESH, (LPARAM)NULL);
  391.  
  392.             return 1;
  393.         }
  394.  
  395.         case WM_COMMAND: {
  396.           static LPCINFO     lpCInfo;
  397.           static SELECTINFO  Select;
  398.  
  399.           //
  400.           // Retrieving this child window's DRVCHILDINFO data for displaying
  401.           //    messages in the text window
  402.           //
  403.           lpCInfo = (LPCINFO) GetWindowLong(hwnd, GWL_USERDATA);
  404.  
  405.           if (!lpCInfo) {
  406.               ErrorMsg(TEXT("DrvWndProc: WM_COMMAND: lpCInfo is NULL."));
  407.               return FALSE;
  408.           }
  409.           
  410.           switch (LOWORD(wParam)){
  411.  
  412.             //
  413.             //  Clears the selection in the active window.
  414.             //  Sent when user hits escape key.
  415.             //
  416.             case MM_ESCAPE:{
  417.                 //
  418.                 // If there is a directory expand in process, kill the
  419.                 //  thread, and leave the listbox in a semi-expanded state.
  420.                 //  Else, clear file selection, and switch to command window.
  421.                 //
  422.                 if( WaitForSingleObject( lpCInfo->hDirMutex, MUTEX_TIMEOUT)
  423.                         == WAIT_TIMEOUT ){
  424.                     lpCInfo->fSuicide = TRUE;
  425.                     lpCInfo->fEscape = TRUE;
  426.                 }
  427.                 else
  428.                     ReleaseMutex( lpCInfo->hDirMutex );
  429.  
  430.                 SendMessage(lpCInfo->hFileLB, LB_SETCURSEL, (WPARAM)-1,
  431.                                (LPARAM)0);
  432.  
  433.                 return 1;
  434.             }
  435.  
  436.             case MM_ENCRYPT_DECRYPT: {
  437.                 if( ghFocusWnd == lpCInfo->hFileLB ) {
  438.                 RunListBoxItem(lpCInfo, ENCRYPT_DECRYPT);
  439.                 }
  440.                 else
  441.                     if( ghFocusWnd == lpCInfo->hDirLB ){
  442.                         if( !PostMessage(hwnd, WM_COMMAND, MM_FILLDIR,
  443.                                          (LPARAM)0) ){
  444.                             ErrorMsg(TEXT("MM_ENCRYPT_DECRYPT: Filldir failure."));
  445.                             return 0;
  446.                         }
  447.                     }
  448.     
  449.                     return 1;
  450.             }
  451.  
  452.             case MM_SIGN: {
  453.                 if( ghFocusWnd == lpCInfo->hFileLB ) {
  454.                 RunListBoxItem(lpCInfo, SIGN);
  455.                 }
  456.                 else
  457.                     if( ghFocusWnd == lpCInfo->hDirLB ){
  458.                         if( !PostMessage(hwnd, WM_COMMAND, MM_FILLDIR,
  459.                                          (LPARAM)0) ){
  460.                             ErrorMsg(TEXT("MM_SIGN: Filldir failure."));
  461.                             return 0;
  462.                         }
  463.                     }
  464.              
  465.                 return 1;
  466.             }
  467.         
  468.             case MM_VERIFY: {
  469.                 if( ghFocusWnd == lpCInfo->hFileLB ) {
  470.                 RunListBoxItem(lpCInfo, VERIFY);
  471.                 }
  472.                 else
  473.                     if( ghFocusWnd == lpCInfo->hDirLB ){
  474.                         if( !PostMessage(hwnd, WM_COMMAND, MM_FILLDIR,
  475.                                          (LPARAM)0) ){
  476.                             ErrorMsg(TEXT("MM_VERIFY: Filldir failure."));
  477.                             return 0;
  478.                         }
  479.                     }
  480.  
  481.                 return 1;
  482.             }
  483.    
  484.             case MM_EXPAND:{
  485.  
  486.                 lpCInfo->fDirExpand = !lpCInfo->fDirExpand;
  487.  
  488.                 if( lpCInfo->fDirExpand )
  489.                     CheckMenuItem( ghMenu, MM_EXPAND,
  490.                                     MF_BYCOMMAND | MF_CHECKED);
  491.                 else
  492.                     CheckMenuItem( ghMenu, MM_EXPAND,
  493.                                 MF_BYCOMMAND | MF_UNCHECKED);
  494.  
  495.                 if( !SendMessage( (HWND)lpCInfo->hwnd, WM_COMMAND,
  496.                                  (WPARAM)MM_REFRESH, (LPARAM)0 ) ){
  497.                     ErrorMsg(TEXT("MM_EXPAND:  MM_REFRESH failure."));
  498.                     return 0;
  499.                 }
  500.                 return 1;
  501.             }
  502.  
  503.             //
  504.             // refreshes contents of directory and file ListBoxes.
  505.             //
  506.             case MM_REFRESH:{
  507.  
  508.                 DWORD   dwThreadID;
  509.                 INT i, N;
  510.  
  511.                 if( WaitForSingleObject( lpCInfo->hDirMutex, MUTEX_TIMEOUT)
  512.                         == WAIT_TIMEOUT )
  513.                     //
  514.                     // If the full directory expand has been cancled, kill the
  515.                     //  existing thread.
  516.                     //
  517.                     if( !lpCInfo->fDirExpand && !lpCInfo->fSuicide){
  518.                         lpCInfo->fSuicide = TRUE;
  519.                         return 1;
  520.                     }
  521.                     else{
  522.                         return 0;
  523.                     }
  524.  
  525.                 // if set, clear the expand dir. user abort (escape key) flag.
  526.                 if( lpCInfo->fEscape ){
  527.                     lpCInfo->fEscape = FALSE;
  528.                     ReleaseMutex( lpCInfo->hDirMutex );
  529.                     return 1;
  530.                 }
  531.  
  532.                 // At this point, the Dir LB mutex has been grabbed.
  533.  
  534.                 // Clear directory LB.  If expand flag is set, expand all
  535.                 //  directories.  Refill File LB.
  536.                 //
  537.                         
  538.                 N = GetSize(lpCInfo->DirTable);
  539.                                            
  540.                    for (i = 0; i < N; i++)
  541.                        TableRemove(lpCInfo->DirTable, 0);
  542.                    
  543.                    if( SendMessage( lpCInfo->hDirLB, LB_RESETCONTENT,
  544.                                  (WPARAM)0, (LPARAM)0 ) < 0 ){
  545.                     ErrorMsg(TEXT("Refresh Drv window: Reset Dir LB content failure."));
  546.                     ReleaseMutex( lpCInfo->hDirMutex );
  547.                     return 0;
  548.                 }
  549.  
  550.                  //
  551.                 // This call puts the default root entry back into the empty
  552.                 //  LB.  Set suicide flag to false to ensure it will complete.
  553.                 //
  554.                 lpCInfo->fSuicide = FALSE;
  555.                 ExpDir( lpCInfo );
  556.  
  557.                 //
  558.                 // All the Dir LB work is done.  Release Dir LB Mutex.
  559.                 //
  560.                 ReleaseMutex( lpCInfo->hDirMutex );
  561.  
  562.                 if( lpCInfo->fDirExpand ){
  563.  
  564.                     CloseHandle( lpCInfo->hDirThread );
  565.  
  566.                     lpCInfo->hDirThread = CreateThread( NULL, 0,
  567.                                   (LPTHREAD_START_ROUTINE)FullExpand,
  568.                                   (LPVOID)lpCInfo, 0, &dwThreadID);
  569.  
  570.                     if( !lpCInfo->hDirThread ){
  571.                         ErrorMsg(TEXT("MM_REFRESH: FullExpand CreateThread failure."));
  572.                         return 0;
  573.                     }
  574.                 }
  575.                 else
  576.                     ExpDir( lpCInfo );
  577.  
  578.                 if( !PostMessage(hwnd, WM_COMMAND, MM_FILLFILE,
  579.                                  (LPARAM)0) ){
  580.                     ErrorMsg(TEXT("Refresh Drv window: Fillfile failure."));
  581.                     return 0;
  582.                 }
  583.  
  584.                 return 1;
  585.             }
  586.  
  587.             //
  588.             //  Fill listbox in lParam with directory from Drv child's drive.
  589.             //  Sent by MM_REFRESH.
  590.             //
  591.             //  lParam == 0
  592.             //
  593.             case MM_FILLDIR:{
  594.  
  595.                 DWORD   dwThreadID;
  596.  
  597.                 lpCInfo->fSuicide = FALSE;
  598.  
  599.                 CloseHandle( lpCInfo->hDirThread );
  600.  
  601.                 lpCInfo->hDirThread = CreateThread( NULL, 0,
  602.                               (LPTHREAD_START_ROUTINE)ExpDir,
  603.                               (LPVOID)lpCInfo, 0, &dwThreadID);
  604.  
  605.                 if( !(lpCInfo->hDirThread) ){
  606.                     ErrorMsg(TEXT("MM_FILLDIR: ExpDir CreateThread failure."));
  607.                     return 0;
  608.                 }
  609.  
  610.                 return 1;
  611.             }
  612.  
  613.             //
  614.             //  Fill listbox in lParam with files from current directory.
  615.             //  Sent by MM_REFRESH & LBN_DBLCLK in DrvWndProc.
  616.             //
  617.             //  lParam == 0
  618.             //
  619.             case MM_FILLFILE:
  620.                 ghFocusWnd = lpCInfo->hFileLB;
  621.                 return FillFile(lpCInfo, hwnd);
  622.                 break;
  623.  
  624.             //
  625.             // The following WM_COMMAND messages are sent by the listboxes
  626.             //
  627.             // HIWORD(wParam) = LB notification message
  628.             // lParam = LB window handle
  629.             //
  630.             case LISTFILE_ID:{
  631.               switch( HIWORD(wParam) ){
  632.                 //
  633.                 // In case of double click on a directory, expand the file
  634.                 // Listbox. if on a file name, run or edit file.
  635.                 //
  636.                 case LBN_DBLCLK:{
  637.                     RunListBoxItem(lpCInfo, ENCRYPT_DECRYPT);
  638.                     return 1;
  639.                 }
  640.                 break;
  641.  
  642.                 case LBN_SETFOCUS:{
  643.                     ghFocusWnd = lpCInfo->hFileLB;
  644.                 }
  645.                 break;
  646.  
  647.                 default:
  648.                     return 1;
  649.               }
  650.             } // LISTFILE_ID
  651.             break;
  652.  
  653.             //
  654.             // Notification from the Directory ListBox
  655.             //
  656.             case LISTDIR_ID:{
  657.               switch( HIWORD(wParam) ){
  658.  
  659.                 case LBN_SETFOCUS:{
  660.                     ghFocusWnd = lpCInfo->hDirLB;
  661.                 }
  662.                 break;
  663.  
  664.                 //
  665.                 // Expand subdirectories in dir listbox
  666.                 //
  667.                 case LBN_DBLCLK:{
  668.  
  669.                     if( !PostMessage(hwnd, WM_COMMAND, MM_FILLDIR,
  670.                                      (LPARAM)0) ){
  671.                         ErrorMsg(TEXT("Dir ListBox Notify: Filldir failure."));
  672.                         return 0;
  673.                     }
  674.                     return 1;
  675.                 }
  676.                 break;
  677.  
  678.                 case LBN_SELCHANGE:{
  679.                     //
  680.                     // for the Directory LB, fill the
  681.                     // corresp. File LB with items in the newly selected dir.
  682.                     //
  683.                     LONG lIndex;
  684.  
  685.                     if( WaitForSingleObject( lpCInfo->hDirMutex, MUTEX_TIMEOUT)
  686.                             == WAIT_TIMEOUT ){
  687.                         ErrorMsg(TEXT("Dir LB Notify: Dir LB Mutex Timeout."));
  688.                         return 0;
  689.                     }
  690.  
  691.                     //
  692.                     // Retrieve selected (careted) item.
  693.                     //
  694.                     lIndex = SendMessage( (HWND)lParam, LB_GETCARETINDEX,
  695.                                         (WPARAM)NULL, (LPARAM)NULL );
  696.  
  697.                     if( !ConstructDirName(lpCInfo, lIndex,
  698.                                           lpCInfo->CaptionBarText) ){
  699.                         ErrorMsg(TEXT("Dir LB Notify:  ConstructDirName failure."));
  700.                         ReleaseMutex( lpCInfo->hDirMutex );
  701.                         return 0;
  702.                     }
  703.  
  704.                     ReleaseMutex( lpCInfo->hDirMutex );
  705.  
  706.                     if( !PostMessage(hwnd, WM_COMMAND, MM_FILLFILE,
  707.                                      (LPARAM)0) ){
  708.                         ErrorMsg(TEXT("Dir ListBox Notify: Fillfile failure."));
  709.                         return 0;
  710.                     }
  711.                 } // LBN_SELCHANGE
  712.                 break;
  713.  
  714.                 default:
  715.                     return 1;
  716.               }
  717.             } //  LISTDIR_ID
  718.             break;
  719.  
  720.             default:
  721.                return 1;
  722.           }
  723.         }
  724.         break;
  725.  
  726.         //
  727.         // Whenever the Drv child window is resized, its children has to be
  728.         //  resized accordingly.  The GetWindowLong GWL_USERDATA values
  729.         //  contain the height of the windows queried, set in their respective
  730.         //  WM_CREATE cases.
  731.         //
  732.         case WM_SIZE: {
  733.             LPCINFO     lpCInfo;
  734.  
  735.             int         nListHeight,
  736.                         nListWidth;
  737.  
  738.             HWND        hLeftLB,
  739.                         hRightLB;
  740.  
  741.             //
  742.             // First, get the text window's handle from the per Drv child
  743.             //  DRVCHILDINFO data structure
  744.             //
  745.             lpCInfo = (LPCINFO)GetWindowLong(hwnd, GWL_USERDATA);
  746.  
  747.             if (!lpCInfo) {
  748.                 ErrorMsg(TEXT("DrvWndProc: WM_SIZE: lpCInfo is NULL."));
  749.                 return 0;
  750.             }
  751.             
  752.             nListHeight = HIWORD(lParam) -
  753.                           GetWindowLong(lpCInfo->hTextWnd, GWL_USERDATA)
  754.                           - LIST_BORDER * 2;
  755.  
  756.             nListWidth = (LOWORD(lParam) - LIST_BORDER) / 2 - LIST_BORDER;
  757.  
  758.             //
  759.             // Always, put the text window at the top of the Drv window.
  760.             // Increasing sides and bottom extents by 1 to overlap border
  761.             //   with Drv child border
  762.             //
  763.             MoveWindow(lpCInfo->hTextWnd,
  764.                        -1,
  765.                        0,
  766.                        LOWORD(lParam) + 2,
  767.                        GetWindowLong(lpCInfo->hTextWnd, GWL_USERDATA) + 1,
  768.                        TRUE);
  769.  
  770.             if( lpCInfo->fDirLeft ){
  771.                 hLeftLB = lpCInfo->hDirLB;
  772.                 hRightLB = lpCInfo->hFileLB;
  773.             }
  774.             else{
  775.                 hLeftLB = lpCInfo->hFileLB;
  776.                 hRightLB = lpCInfo->hDirLB;
  777.             }
  778.  
  779.             MoveWindow(hLeftLB,
  780.                        LIST_BORDER,
  781.                        GetWindowLong(lpCInfo->hTextWnd, GWL_USERDATA) + 1
  782.                          + LIST_BORDER,
  783.                        nListWidth,
  784.                        nListHeight,
  785.                        TRUE);
  786.  
  787.             MoveWindow(hRightLB,
  788.                        (LOWORD(lParam) + LIST_BORDER) / 2,
  789.                        GetWindowLong(lpCInfo->hTextWnd, GWL_USERDATA) + 1
  790.                          + LIST_BORDER,
  791.                        nListWidth,
  792.                        nListHeight,
  793.                        TRUE);
  794.  
  795.         break;
  796.         }
  797.  
  798.         case WM_PARENTNOTIFY:{
  799.             LPCINFO lpCInfo;
  800.  
  801.             if(wParam == WM_LBUTTONDOWN){
  802.                 lpCInfo = (LPCINFO) GetWindowLong(hwnd, GWL_USERDATA);
  803.                 if(lpCInfo == NULL){
  804.                     ErrorMsg(TEXT("Drv child: Parent notify failure."));
  805.                     return 1;
  806.                 }
  807.                 if(HIWORD(wParam) == LISTDIR_ID)
  808.                     SetFocus(lpCInfo->hDirLB);
  809.                 else
  810.                     if(HIWORD(wParam) == LISTFILE_ID)
  811.                         SetFocus(lpCInfo->hFileLB);
  812.                     else
  813.                         if(HIWORD(wParam) == TEXT_WINDOW_ID)
  814.                             SetFocus(lpCInfo->hTextWnd);
  815.             }
  816.  
  817.             break;
  818.         }
  819.  
  820.         //
  821.         // Same as MainWndProc's MM_ACTIVEDRV case.  The initial PostMessage
  822.         //   is so the currently active Drv child will not process the message
  823.         //   until it is no longer in focus.
  824.         //
  825.         case WM_MOUSEACTIVATE:{
  826.             LPCINFO lpCInfo;
  827.  
  828.             PostMessage(ghwndDrv, WM_COMMAND, (WPARAM)MM_TOGGLE,
  829.                         (LPARAM)NULL);
  830.             ghwndDrv = hwnd;
  831.             SendMessage(ghwndDrv, WM_COMMAND, (WPARAM)MM_TOGGLE,
  832.                         (LPARAM)NULL);
  833.  
  834.             lpCInfo = (LPCINFO) GetWindowLong(hwnd, GWL_USERDATA);
  835.             
  836.             if (!lpCInfo) {
  837.                 ErrorMsg(TEXT("DrvWndProc: lpCInfo is NULL."));
  838.                 return FALSE;
  839.             }
  840.             
  841.             SendMessage(ghwndDrives, WM_COMMAND, MM_ACTIVEDRV,
  842.                         (LPARAM)lpCInfo->lpDriveInfo);
  843.  
  844.             break;
  845.         }
  846.  
  847.         //
  848.         // Free the DRVCHILDINFO data that associates with this window
  849.         //  also, reset the menu.
  850.         //
  851.         case WM_CLOSE: {
  852.             LPCINFO lpCInfo;
  853.             
  854.             lpCInfo = (LPCINFO)GetWindowLong(hwnd, GWL_USERDATA);
  855.             
  856.             if (!lpCInfo) {
  857.                 ErrorMsg(TEXT("DrvWndProc: WM_CLOSE: lpCInfo is NULL."));
  858.                 return 0;
  859.             }
  860.             
  861.             CloseHandle(lpCInfo->hDirThread);
  862.             CloseHandle(lpCInfo->hDirMutex );
  863.             CloseHandle(lpCInfo->hFileMutex );
  864.             TableFree(lpCInfo->DirTable);
  865.             TableFree(lpCInfo->FileTable);
  866.             
  867.             break;
  868.         }
  869.  
  870.                 //   case WM_DELETEITEM:
  871.             case WM_DRAWITEM: {
  872.             
  873.                 // Get pointer to the DRAWITEMSTRUCT 
  874.                 lpdis = (LPDRAWITEMSTRUCT)lParam;
  875.  
  876.                 switch (lpdis->itemAction)
  877.                 {
  878.                     case ODA_DRAWENTIRE:
  879.                         DrawEntireItem(lpdis);
  880.                         break;
  881.  
  882.                     case ODA_SELECT:
  883.                         HandleSelectionState(lpdis);
  884.                         break;
  885.                     
  886.                 }
  887.  
  888.                   // Return TRUE meaning that we processed this message. 
  889.                 return 1;
  890.             }
  891.  
  892.             case WM_MEASUREITEM:{
  893.                
  894.                 lpmis = (LPMEASUREITEMSTRUCT)lParam;
  895.             
  896.  
  897.                 // All the items are the same height since the list box style is
  898.                 // LBS_OWNERDRAWFIXED
  899.                 //
  900.                 lpmis->itemHeight = 15;
  901.                 return 1;
  902.             }        
  903.             
  904.             case WM_COMPAREITEM: {
  905.                 INT cv;
  906.                 
  907.                 lpcis = (LPCOMPAREITEMSTRUCT)lParam;
  908.  
  909.                 if (!lpcis->itemData1)
  910.                     ErrorMsg(TEXT("WM_COMPAREITEM: lpcis->itemData1 is NULL."));
  911.                 
  912.                 if (!lpcis->itemData2)
  913.                     ErrorMsg(TEXT("WM_COMPAREITEM: lpcis->itemData2 is NULL."));
  914.                 
  915.                 cv = CFilerlstrcmp((LPTSTR)(lpcis->itemData1), (LPTSTR)(lpcis->itemData2));
  916.                                 
  917.                 if (cv < 0)
  918.                     return -1;
  919.                 else if (cv == 0)
  920.                     return 0;
  921.                 else if (cv > 0)
  922.                     return 1;
  923.             
  924.             }
  925.             
  926.             default:
  927.             return DefWindowProc(hwnd, message, wParam, lParam);
  928.  
  929.     } //switch
  930.     return DefWindowProc(hwnd, message, wParam, lParam);
  931. }
  932.  
  933. /*************************************************************************************\
  934. * TextWndProc()
  935. *
  936. * Text Window procedure for displaying miscellaneous messages to user.
  937. \*************************************************************************************/
  938.  
  939. LRESULT WINAPI TextWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  940. {
  941.  
  942.     switch (message)
  943.     {
  944.     case WM_CREATE:
  945.         {
  946.         HDC        hDC;
  947.         HGDIOBJ    hOldFont;
  948.         TEXTMETRIC tm;
  949.         LONG       lHeight;
  950.  
  951.         hDC = GetDC(hwnd);
  952.  
  953.         hOldFont = SelectObject(hDC, ghFont);
  954.         GetTextMetrics(hDC, &tm);
  955.  
  956.         //
  957.         // base the height of the window on size of text
  958.         //
  959.         lHeight = tm.tmHeight + GetSystemMetrics(SM_CYBORDER) + 6;
  960.  
  961.         //
  962.         // saved the height for later reference
  963.         //
  964.         SetWindowLong(hwnd, GWL_USERDATA, lHeight);
  965.  
  966.             if(hOldFont)
  967.                 SelectObject(hDC, hOldFont);
  968.  
  969.             ReleaseDC(hwnd, hDC);
  970.             break;
  971.         }
  972.  
  973.     case WM_SETTEXT:
  974.             DefWindowProc(hwnd, message, wParam, lParam);
  975.             if( !InvalidateRect(hwnd, NULL, TRUE) ){
  976.                 ErrorMsg(TEXT("Textwindow: Set text failure."));
  977.                 return 1;
  978.             }
  979.             UpdateWindow(hwnd);
  980.             return 1;
  981.  
  982.     case WM_PAINT:
  983.         {
  984.             PAINTSTRUCT ps;
  985.             RECT        rc;
  986.             TCHAR       ach[BUF_SIZE];
  987.             int         len, nxBorder, nyBorder;
  988.             HFONT       hOldFont = NULL;
  989.             HBRUSH      hBrush;
  990.  
  991.             BeginPaint(hwnd, &ps);
  992.  
  993.             GetClientRect(hwnd,&rc);
  994.  
  995.             len = GetWindowText(hwnd, ach, BUF_SIZE);
  996.  
  997.             SetBkMode(ps.hdc, TRANSPARENT);
  998.  
  999.             if( GetParent(hwnd) == ghwndDrv ){
  1000.                 hBrush = CreateSolidBrush( GetSysColor(COLOR_ACTIVECAPTION) );
  1001.                 SetTextColor( ps.hdc, GetSysColor(COLOR_CAPTIONTEXT) );
  1002.             }
  1003.             else{
  1004.                 hBrush = CreateSolidBrush( GetSysColor(COLOR_INACTIVECAPTION) );
  1005.                 SetTextColor( ps.hdc, GetSysColor(COLOR_INACTIVECAPTIONTEXT) );
  1006.             }
  1007.  
  1008.             hOldFont = SelectObject(ps.hdc, ghFont);
  1009.  
  1010.             FillRect(ps.hdc, &rc, hBrush);
  1011.  
  1012.             nxBorder = GetSystemMetrics(SM_CXBORDER);
  1013.             rc.left  += 9*nxBorder;
  1014.             rc.right -= 9*nxBorder;
  1015.  
  1016.             nyBorder = GetSystemMetrics(SM_CYBORDER);
  1017.             rc.top    += 3*nyBorder;
  1018.             rc.bottom -= 3*nyBorder;
  1019.  
  1020.             ExtTextOut(ps.hdc, rc.left+2*nxBorder, rc.top, ETO_CLIPPED,
  1021.                     &rc, ach, len, NULL);
  1022.  
  1023.             SetBkMode(ps.hdc, OPAQUE);
  1024.  
  1025.             if (hOldFont)
  1026.                 SelectObject(ps.hdc, hOldFont);
  1027.  
  1028.             DeleteObject(hBrush);
  1029.  
  1030.             EndPaint(hwnd, &ps);
  1031.             return 1;
  1032.         }
  1033.     }
  1034.     return DefWindowProc(hwnd, message, wParam, lParam);
  1035. }
  1036.