home *** CD-ROM | disk | FTP | other *** search
/ Windows Shareware GOLD / NuclearComputingVol3No1.cdr / utils / f1296 / wdn.c < prev    next >
C/C++ Source or Header  |  1990-12-03  |  25KB  |  964 lines

  1. /*SDOC*************************************************************
  2.  
  3.  
  4.  
  5.  
  6. WW      WW DDDDDDDDD  NN      NN 
  7. WW      WW DDDDDDDDDD NNN     NN 
  8. WW      WW DD      DD NNNN    NN 
  9. WW      WW DD      DD NNNNN   NN 
  10. WW      WW DD      DD NN NNN  NN 
  11. WW  WW  WW DD      DD NN  NNN NN 
  12. WW WWWW WW DD      DD NN   NNNNN 
  13. WWWWWWWWWW DD      DD NN    NNNN 
  14. WWWW  WWWW DDDDDDDDDD NN     NNN 
  15. WWW    WWW DDDDDDDDD  NN      NN 
  16.  
  17.     $Header$
  18.  
  19.     Module: WDN
  20.  
  21.     Author:    Pat Beirne
  22.  
  23.     Copyright 1990 Corel Systems Corp.
  24.  
  25.     Description: 
  26.         Windows version of DIRNOTES
  27.  
  28.     Things to do:
  29.         all done....
  30.  
  31. *************************************************************EDOC*/
  32.  
  33. /*SDOC*************************************************************
  34.  
  35.   Revision Record
  36.  
  37.     Rev    Date        Auth    Changes
  38.     ===    ====        ====    =======
  39.  
  40.     0.0    26/11/90    pb      start
  41.     0.2    30/11/90 pb        internal release
  42.     1.0    04/12/90 pb        release 1
  43.  
  44. *************************************************************EDOC*/
  45.  
  46.  
  47. /*
  48. **
  49. **     Includes
  50. **
  51. */
  52. #include <windows.h>
  53. #include <stdio.h>
  54. #include <io.h>
  55. #include <dos.h>
  56. #include <stdlib.h>
  57. #include <fcntl.h>
  58. #include <ctype.h>
  59. #include <string.h>
  60. #include <direct.h>
  61.  
  62. #include "wdn.h"
  63.  
  64. #ifndef DEBUG
  65. #define MessageBeep(x) 
  66. #define DD ;/##/ 
  67. #else
  68. #define DD DbugShow
  69. #endif
  70.  
  71. /*::defn
  72. **
  73. **     Defines
  74. **
  75. */
  76.  
  77.  
  78. #define MAX_BUF 2048        // the file read buffer
  79.  
  80. #define BROWN RGB(180,100,0)    // the text colors
  81. #define BLACK RGB(30,50,0)
  82.  
  83.  
  84.     /* ASCII */
  85. #define BS  8
  86. #define TAB  9
  87. #define LF  10
  88. #define FF  12
  89. #define CR  13
  90. #define ESC  27
  91. #define TAB_SIZE 4
  92.  
  93. #define HMEM HANDLE
  94.  
  95. typedef struct tagDirEntry
  96. {
  97.     char    sName[9];        // always ends in space; left justified
  98.     char    sExt[4];            // always ends in space; left justified
  99.     char    sSize[8];        // in ascii decimal, right justified
  100.     char     sPad[2];
  101.     char    sDate[8];
  102.     char    sPad1[2];
  103.     char    sTime[6];
  104.     char    sNew[2];            // is either "U " or "  "
  105.     char    sComment[38];    // pad out to 80 chars
  106.     char    sCRLF[2];        // always CR/LF
  107. } DIRENTRY;
  108. #define POS_SIZE 13
  109. #define POS_COMMENTS 41
  110. #define LINE_LENGTH 81        // DOS converts CR/LF to CR only
  111. /*::end*/
  112.  
  113.  
  114. /*::decl
  115. **
  116. **     Global Variables
  117. **
  118. */
  119.  
  120. char szFrame[] = APP_NAME;
  121. int     hInst;        // the instance
  122. HWND hWnd;            // the main (and only) window
  123. HWND hListBox;        // the directory list box
  124. HWND hEditBox;        // the edit control
  125. char szBuf[LINE_LENGTH+1];
  126. char szBuf2[LINE_LENGTH+1];
  127.  
  128. int     fDirty = FALSE;    // set once the file has been modified
  129. int    fLocalDirty = FALSE; // set onece the line has been modified
  130. int    nCharWidth, nCharHeight;        // from the system font
  131. int    nLBCharWidth, nLBCharHeight;    // from the mono-spaced system font
  132. int    nScrollWidth;        // the width of the vscroll bar
  133. OFSTRUCT ofs;                        // holds the full name of the notes file
  134. char    szFileName[_MAX_FNAME + _MAX_EXT + 1];    // the file to match to formated "nnnnnnnn eee"
  135. char    szNoteFile[_MAX_FNAME + _MAX_EXT + 1];    // the file that holds the notes form "nnnnnnnn.eee"
  136. char    szFName[_MAX_FNAME];        // scratch
  137. char    szExt[_MAX_EXT];            // scratch
  138. char    szDrive[_MAX_DRIVE];        // the path we're working on
  139. char    szDir[_MAX_DIR];            // the drive we're working on
  140.  
  141. FARPROC lpEditProc;                // holds the sub-classed edit proc
  142. FARPROC lpEditSubClassProc;
  143. FARPROC lpDirsProc;                // holds the sub-classed dir listbox proc
  144. FARPROC lpDirsSubClassProc;
  145. /*::end*/
  146.  
  147.  
  148. /*::fnproto
  149. **
  150. **     Function Prototypes
  151. **
  152. */
  153. void Paint(HWND hwnd);
  154. LONG FAR PASCAL FrameWndProc (HWND hwnd, WORD msg,WORD wParam, LONG lParam );
  155. void cdecl far DbugShow(HWND hWind,char *szFormat,...);
  156. HWND WakeUp(HANDLE hInst, int nStartup);
  157. int  Init(void);
  158. WORD FillListBox(HWND hListBox);
  159. void LocateChildWindows(HWND hWnd);
  160. BOOL CommandLine(LPSTR lpCmdLine);
  161. BOOL SaveFile(HWND hWnd);
  162. void CopyComments(HWND hListBox, HWND hEditBox);
  163. int  SearchForGivenFile(HWND hLB);
  164. char *StripWhiteSpace(char *str);
  165. void NewDir(HWND hwnd,HWND hDirs);
  166. BOOL ParseAndFill(HWND hWnd, LPSTR lpCmdLine);
  167. BOOL FAR PASCAL AboutBox(HWND hDlg, WORD message, WORD wParam, LONG lParam);
  168. LONG FAR PASCAL EditSubClassProc(HWND hEdit, WORD message, WORD wParam, LONG lParam);
  169. LONG FAR PASCAL DirsSubClassProc(HWND hList, WORD message, WORD wParam, LONG lParam);
  170.  
  171. /*::end*/
  172.  
  173.  
  174. /*
  175. **
  176. **     Local Variables
  177. **
  178. */
  179.  
  180.  
  181.  
  182.  
  183.  
  184. /*SDOC*************************************************************
  185.  
  186.     Name: WinMain
  187.  
  188.     Action: 1) wake up the instance; create the class, if required
  189.             2) parse the command line; try to find the file
  190.             3) wake up the main window
  191.             4) message loop
  192.  
  193.     Returns: when user quits
  194.  
  195. *************************************************************EDOC*/
  196.  
  197. extern int __argc;
  198. extern char **__argv;
  199.  
  200.  
  201. int NEAR PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  202.  
  203. HANDLE hInstance;
  204. HANDLE hPrevInstance;
  205. LPSTR  lpszCmdLine;
  206. int    nCmdShow;
  207. {
  208.     MSG msg;
  209.     HWND hWnd;
  210.  
  211.     hInst = hInstance;
  212.     /* If this is the first instance of the app. register window classes */
  213.     if (!hPrevInstance)
  214.         if (!Init()) return FALSE;
  215.  
  216.  
  217.     hWnd = WakeUp(hInstance,nCmdShow);
  218.     if (!hWnd) return 1;
  219.  
  220.     if (!ParseAndFill(hWnd,lpszCmdLine))
  221.         return 1;
  222.  
  223.     /* Enter main message loop */
  224.     while (GetMessage (&msg, NULL, 0, 0))
  225.         {
  226.         if (!IsDialogMessage(hWnd,&msg))
  227.             {
  228.            TranslateMessage (&msg);
  229.            DispatchMessage (&msg);
  230.             }
  231.        }
  232.  
  233.     if (lpEditSubClassProc) FreeProcInstance(lpEditSubClassProc);
  234.     if (lpDirsSubClassProc) FreeProcInstance(lpDirsSubClassProc);
  235.  
  236.     return 0;
  237. }
  238.  
  239.  
  240. LONG FAR PASCAL FrameWndProc ( hwnd, msg, wParam, lParam )
  241. register HWND     hwnd;
  242. WORD         msg;
  243. register WORD     wParam;
  244. LONG         lParam;
  245. {
  246.     switch(msg)
  247.         {
  248.         case WM_SIZE:
  249.             LocateChildWindows(hwnd);
  250.             break;
  251.  
  252.         case WM_DESTROY:
  253.             if (fDirty)
  254.                 {
  255.                 CopyComments(hListBox,hEditBox);
  256.                 SaveFile(hwnd);
  257.                 }
  258.             PostQuitMessage(0);
  259.             break;
  260.  
  261.         case WM_SETFOCUS:
  262.             SetFocus(hEditBox);
  263.             break;
  264.  
  265.  
  266.         case WM_INITMENU:
  267.             if ((HMENU)wParam != GetMenu(hwnd)) break;
  268.             EnableMenuItem((HMENU)wParam,
  269.                     WM_UNDO,
  270.                     (SendMessage(hEditBox,EM_CANUNDO,0,0L))
  271.                         ?     MF_ENABLED : MF_GRAYED);
  272.             OpenClipboard(hwnd);
  273.             EnableMenuItem((HMENU)wParam,
  274.                     WM_PASTE,
  275.                     (IsClipboardFormatAvailable(CF_TEXT))
  276.                         ?     MF_ENABLED : MF_GRAYED);
  277.             CloseClipboard();
  278.                 {
  279.                 long sel = 
  280.                     (SendMessage(hEditBox,EM_GETSEL,0,0L));
  281.                 EnableMenuItem((HMENU)wParam,
  282.                     WM_CUT,
  283.                     HIWORD(sel) != LOWORD(sel) 
  284.                         ?     MF_ENABLED : MF_GRAYED);
  285.                 EnableMenuItem((HMENU)wParam,
  286.                     WM_COPY,
  287.                     HIWORD(sel) != LOWORD(sel) 
  288.                         ?     MF_ENABLED : MF_GRAYED);
  289.                 }
  290.             break;
  291.  
  292.         case WM_COMMAND:
  293. //            DD(hwnd,"got a message from a child %d %lx",wParam,lParam);
  294.             switch (wParam)
  295.                 {
  296.                 case CM_FILE_QUIT:
  297.                     fDirty = FALSE;        // mark for abort and fall through
  298.                 case CM_FILE_EXIT:
  299.                     DestroyWindow(hwnd);
  300.                     break;
  301.                 case CDD_LISTBOX:
  302. //                    DD(hwnd,"list box message %lx",lParam);
  303.                     if (HIWORD(lParam) == LBN_SELCHANGE)
  304.                         CopyComments(hListBox,hEditBox);
  305.                     break;
  306.                 case CDD_EDIT:
  307.                         // if the comment changes, and the abort flag not set...
  308.                     if (HIWORD(lParam) == EN_CHANGE)
  309.                         fDirty = fLocalDirty = TRUE;
  310.                     break;
  311.                 case CDD_DIRS:
  312.                     DD(hwnd,"message from dir box %x %lx",wParam,lParam);
  313.                     switch(HIWORD(lParam))
  314.                         {
  315.                         case LBN_DBLCLK:
  316. //                        case LBN_SELCHANGE:
  317.                             NewDir(hwnd,(HWND) LOWORD(lParam));
  318.                             break;
  319.                         }
  320.                     break;
  321.                 case WM_CUT:
  322.                 case WM_COPY:
  323.                 case WM_PASTE:
  324.                 case WM_UNDO:
  325.                     SendMessage(hEditBox,wParam,wParam,lParam);
  326.                     break;
  327.                 case CM_FILE_ABOUT:
  328.                     {
  329.                     FARPROC lpProc;
  330.  
  331.                     lpProc = MakeProcInstance( AboutBox, hInst );
  332.                     DialogBox(hInst,"WDN_ABOUT", hWnd, lpProc);
  333.                     FreeProcInstance(lpProc);
  334.                     }
  335.                     break;
  336.                 }
  337.             break;
  338.         default:
  339.             return DefWindowProc(hwnd,msg,wParam,lParam);
  340.             break;
  341.         }
  342.     return 0L;
  343. }
  344.  
  345.  
  346. int Init(void)
  347. {
  348.    WNDCLASS    wc;
  349.  
  350.       /* Register the frame class */
  351.    wc.style         = NULL;
  352.    wc.lpfnWndProc   = FrameWndProc;
  353.    wc.cbClsExtra    = 0;
  354.    wc.cbWndExtra    = DLGWINDOWEXTRA;
  355.    wc.hInstance     = hInst;
  356.    wc.hIcon         = LoadIcon(hInst,MAKEINTRESOURCE(IDPREVIEW));
  357.    wc.hCursor         = LoadCursor(NULL,IDC_ARROW);
  358. //   wc.hbrBackground = COLOR_APPWORKSPACE+1;
  359.    wc.hbrBackground = COLOR_WINDOW+1;
  360.    wc.lpszMenuName  = NULL;
  361.    wc.lpszClassName = szFrame;
  362.  
  363.    if (!RegisterClass (&wc) )
  364.     return FALSE;
  365.  
  366. }
  367.  
  368. /*SDOC*************************************************************
  369.  
  370.     Name: WakeUp
  371.  
  372.     Action: creates the main app, and the windows within it
  373.  
  374.     Returns: the handle to the main app window
  375.  
  376. *************************************************************EDOC*/
  377. HWND WakeUp(HANDLE hInst, int nCmdShow)
  378. {
  379.     HMENU hMenu;
  380.     HWND hWnd;
  381.     HFONT hFont;
  382.     TEXTMETRIC tm;
  383.     HDC    hDC;
  384.     HWND     hDirs;
  385.  
  386.     DD(122,"just about to create 4 windows");
  387.     DD(122,"premenu load");
  388.     hMenu = LoadMenu(hInst,"WDN_MENU");
  389.     DD(122,"menu loaded");
  390.  
  391.     hWnd = CreateDialog(hInst,"WDN",0,NULL);
  392.     hListBox = GetDlgItem(hWnd,CDD_LISTBOX);
  393.     hEditBox = GetDlgItem(hWnd,CDD_EDIT);
  394. MessageBeep(5);
  395. DD(hWnd,"did the CreateDialog() create");
  396.  
  397.     if (!hEditBox || !hListBox || !hWnd)
  398.         return NULL;
  399.  
  400.     // get the dimensions of the two fonts
  401.     // new version
  402.     nCharWidth = LOWORD(GetDialogBaseUnits());
  403.     nCharHeight = HIWORD(GetDialogBaseUnits());
  404.     // old version
  405. //    GetTextMetrics(hDC,&tm);
  406. //    nCharWidth = tm.tmAveCharWidth;
  407. //    nCharHeight = tm.tmHeight;
  408.     hDC = GetDC(hWnd);
  409.     hFont = GetStockObject(SYSTEM_FIXED_FONT);
  410.     if (!hFont) hFont = GetStockObject(ANSI_FIXED_FONT);
  411. DD(hWnd,"located the fixed font %x",hFont);
  412.     SelectObject(hDC,hFont);
  413.     GetTextMetrics(hDC, &tm);
  414.     ReleaseDC(hWnd,hDC);
  415.     nLBCharWidth = tm.tmAveCharWidth;
  416.     nLBCharHeight = tm.tmHeight;
  417.     nScrollWidth = GetSystemMetrics(SM_CXVSCROLL);
  418.  
  419.     SendMessage(hEditBox,EM_LIMITTEXT,LINE_LENGTH-POS_COMMENTS-2,0L);
  420.     DD(hWnd,"edit window created %x",hEditBox);
  421.  
  422.     SendMessage(hListBox,WM_SETFONT,hFont,0L);
  423. DD(hListBox,"listbox uses font %x instead of %x",(int)SendMessage(hListBox,WM_GETFONT,0,0L),hFont);
  424. //MessageBox(hWnd,"test","test",MB_OK);
  425.  
  426.     LocateChildWindows(hWnd);
  427.  
  428.     lpEditProc = (FARPROC) GetWindowLong(hEditBox,GWL_WNDPROC);
  429.     lpEditSubClassProc = MakeProcInstance((FARPROC)EditSubClassProc,hInst);
  430.     SetWindowLong(hEditBox,GWL_WNDPROC,(LONG)lpEditSubClassProc);
  431.  
  432.     hDirs = GetDlgItem(hWnd,CDD_DIRS);
  433.     lpDirsProc = (FARPROC) GetWindowLong(hDirs,GWL_WNDPROC);
  434.     lpDirsSubClassProc = MakeProcInstance((FARPROC)DirsSubClassProc,hInst);
  435.     SetWindowLong(hDirs,GWL_WNDPROC,(LONG)lpDirsSubClassProc);
  436.  
  437.     return hWnd;
  438. }
  439.  
  440.  
  441. /*SDOC*************************************************************
  442.  
  443.     Name: FillListBox
  444.  
  445.     Action: searches the current drive and fills the listbox with dir data
  446.  
  447.     Returns: the number of entries in the list box
  448.  
  449. *************************************************************EDOC*/
  450. WORD FillListBox(HWND hListBox)
  451. {
  452.     int    cNumber = 0;
  453.     struct     find_t ff;
  454.     int    hFile;
  455.  
  456.     SendMessage(hListBox,WM_SETREDRAW,0,0L);
  457.     SendMessage(hListBox,LB_RESETCONTENT,0,0L);
  458.  
  459.     _makepath(szBuf,szDrive,szDir,"*",".*");
  460.  
  461.     if (!_dos_findfirst(szBuf,_A_NORMAL | _A_SUBDIR | _A_RDONLY | _A_ARCH,&ff))
  462.         {
  463.         do
  464.             {
  465.             char *ext;
  466.             char name[13];
  467.             strncpy(name,ff.name,13);
  468.             if (name[0]=='.') continue;    // skip the dot directories
  469.             if (ext=strchr(name,'.'))
  470.                 *(ext++) = '\0';
  471.             else ext = "   ";
  472.              wsprintf(szBuf2,"%-8.8s %-3.3s %8ld  %2d-%2.2d-%2.2d  %2d:%2.2d%c%c ",
  473.                     (LPSTR) name, (LPSTR) ext,
  474.                     ff.size,
  475.                     (ff.wr_date >> 5)&0xf, (ff.wr_date & 0x1f), 80 + (ff.wr_date >> 9),
  476.                     ((ff.wr_time >>11)+11)%12+1 ,(ff.wr_time >>5) & 0x3f,(WORD)ff.wr_time > 0x6000 ? 'p' : 'a',
  477.                     'U');
  478.             if (ff.attrib & _A_SUBDIR)
  479.                 memmove(szBuf2+POS_SIZE,"<DIR>    ",9);
  480.             SendMessage(hListBox,LB_ADDSTRING,0,(DWORD) (LPSTR)szBuf2);
  481. //DD(hListBox,t);
  482.             }
  483.         while (!_dos_findnext(&ff) && ++cNumber<500);
  484.  
  485.         }
  486.  
  487.     // now, try to open the notes file
  488.     hFile = OpenFile(NULL,&ofs,OF_REOPEN | OF_READWRITE);
  489.     if (hFile != -1)
  490.         {
  491.         int    iSearch = 0;
  492.         int    iFound;
  493.         char    szFile[POS_SIZE+1];
  494.         
  495. DD(123,"opened the file %s",ofs.szPathName);
  496.         // read it in, a line at a time
  497.         while(read(hFile,szBuf,LINE_LENGTH) > 0)
  498.             {
  499. //DD(hListBox,"just read in the line <%s>",szBuf);
  500.  
  501.             StripWhiteSpace(szBuf);
  502.             strncpy(szFile,szBuf,POS_SIZE);
  503.             szFile[POS_SIZE]='\0';
  504.             iFound = (int)SendMessage(hListBox,LB_FINDSTRING,iSearch,(LONG)(LPSTR)szFile);
  505.  
  506.             if (iFound!=LB_ERR)
  507.                 {
  508.                 BOOL fChanged = FALSE;
  509.  
  510.                     // suck the list box stuff into szBuf2
  511.                  SendMessage(hListBox,LB_GETTEXT,iFound,(LONG)(LPSTR)szBuf2);
  512.                     // check for matching size and date
  513.                 if (!strncmp(szBuf+POS_SIZE,szBuf2+POS_SIZE,POS_COMMENTS-POS_SIZE-2))
  514.                     {
  515.                     szBuf2[POS_COMMENTS-2]=' ';
  516.                     fChanged = TRUE;
  517.                     }
  518.  
  519.                     // if there's comments
  520.                 if (strlen(szBuf) > POS_COMMENTS)
  521.                     {
  522.                     strncpy(szBuf2+POS_COMMENTS,szBuf+POS_COMMENTS,LINE_LENGTH-POS_COMMENTS-2);
  523.                     fChanged = TRUE;
  524.                     }
  525.  
  526.                     // put then new stuff back in the list box
  527.                 if (fChanged)
  528.                     {
  529.                     // NOTE the order: don't delete first; it screws up list boxes
  530.                     // especially if the last item is selected
  531.                     SendMessage(hListBox,LB_INSERTSTRING,iFound,(LONG)(LPSTR)szBuf2);
  532.                     SendMessage(hListBox,LB_DELETESTRING,iFound+1,0L);
  533. //DD(hListBox,"insert %d comment <%s>",iFound,szBuf2);
  534.                     }
  535.                 iSearch=iFound;
  536.                 }
  537.             }
  538.         close(hFile);
  539.         }
  540.     SendMessage(hListBox,WM_SETREDRAW,1,0L);
  541.     InvalidateRect(hListBox,NULL,TRUE);
  542. DD(hListBox,"there are %d entries",SendMessage(hListBox,LB_GETCOUNT,0,0L));
  543.  
  544.     return cNumber;
  545. }
  546.  
  547. /*SDOC*************************************************************
  548.  
  549.     Name: LocateChildWindows
  550.  
  551.     Action: resizes the listbox to match the window
  552.  
  553.     Returns: void
  554.  
  555. *************************************************************EDOC*/
  556. void LocateChildWindows(HWND hWnd)
  557. {
  558.     RECT rClient;
  559.     GetClientRect(hWnd,&rClient);
  560.     MoveWindow(hListBox,
  561.         nCharWidth,10*nCharHeight/2,
  562.         min((LINE_LENGTH)*nLBCharWidth+nScrollWidth,
  563.             (rClient.right-2*nCharWidth)),
  564.         rClient.bottom-11*nCharHeight/2,
  565.         TRUE);
  566. }
  567.  
  568. /*SDOC*************************************************************
  569.  
  570.     Name: CommandLine
  571.  
  572.     Action: parse the given command line
  573.         use OpenFile() to parse the command line and resolve the real path
  574.         separate the path
  575.             use the path to define the default notes name
  576.         look at the file name; if it conforms, use it as the notes name
  577.             if it doesn't conform, save it for the wakeup search
  578.         form the full notes name and run OpenFile() to parse it
  579.  
  580.     Returns: TRUE if everything ok
  581.         on the way, it sets
  582.             szDrive        the displayed disk
  583.             szDir            the displayed directory
  584.             szFName        the notes file
  585.             szExt            the notes file
  586.             ofs            the notes file
  587.             szNoteFile    the notes file (file+ext only)
  588.             szFileName    the file to match
  589.  
  590. *************************************************************EDOC*/
  591. BOOL    CommandLine(LPSTR lpCmdLine)
  592. {
  593.     char    szTemp[_MAX_PATH];
  594.     char    *pWalk;
  595.  
  596.         // copy down the text from the far string
  597.     if (lstrlen(lpCmdLine) > _MAX_PATH) return FALSE;
  598.     lstrcpy(szTemp, lpCmdLine);
  599. //DD(123,"got the command line <%s>",szTemp);
  600.  
  601.     strupr(szTemp);
  602.     OpenFile(szTemp,&ofs,OF_PARSE);
  603.     _splitpath(ofs.szPathName,szDrive,szDir,szFName,szExt);
  604.  
  605.         // create the default notes file name
  606.     strcpy(szNoteFile,"DIRN----.DAT");
  607. //DD(123,"made the plain note file name <%s>",szNoteFile);
  608. //DD(123,"after the split, the ext is <%s>",szExt);
  609. //DD(123,"after the split, the dir is <%s> at %x",szDir,szDir);
  610.  
  611.         // point to the last name in the path list
  612.     strcpy(szTemp,szDir);            // use the scratch pad
  613.     pWalk=strrchr(szTemp,'\\');    // strip the last slash
  614.     if (pWalk)
  615.         {
  616.         *pWalk = '\0';                    // walk back to the prev slash
  617.         pWalk=strrchr(szTemp,'\\');
  618.         }
  619.     if (!pWalk) pWalk=szDir;
  620.     if (*(++pWalk))
  621.         {szNoteFile[5]=*pWalk;
  622.         if (pWalk[1])
  623.             {szNoteFile[6]=pWalk[1];
  624.             if (pWalk[2]) szNoteFile[7]=pWalk[2];
  625.             }
  626.         }
  627. DD(123,"overwrote the note file name <%s>",szNoteFile);
  628.  
  629.         // is it not conforming file name?? if so, save it
  630.         //     for a file match and overwrite it with the default name
  631.     if (strncmp(szFName,"DIRN-",5) || (strcmp(szExt,".DAT") && strcmp(szExt,".WDN")))
  632.         {
  633.         wsprintf(szFileName,"%-8.8s %-3.3s",(LPSTR)szFName,(LPSTR)szExt+1);
  634. DD(123,"saved the search file <%s>",szFileName);
  635.         strncpy(szFName,szNoteFile,8);
  636.         szFName[8]='\0';
  637.         strcpy(szExt,szNoteFile+8);
  638.         }
  639.     else
  640.         szFileName[0]='\0';    // clear the match file
  641.  
  642.         // now reform the full notes name
  643.     _makepath(szTemp,szDrive,szDir,szFName,szExt);
  644. DD(123,"just made the full notes name %s",szTemp);
  645.         // and parse it for the open
  646.     OpenFile(szTemp,&ofs,OF_PARSE);
  647.  
  648.     return TRUE;
  649. }
  650.  
  651.  
  652.  
  653. /*SDOC*************************************************************
  654.  
  655.     Name: SaveFile
  656.  
  657.     Action: read the list box and spit the stuff out to file
  658.  
  659.     Returns: TRUE if everything ok
  660.  
  661. *************************************************************EDOC*/
  662. BOOL SaveFile(HWND hWnd)
  663. {
  664.     int    hFile;
  665.     int    i,n;
  666.  
  667. //    MessageBox(hWnd,"saving","saving",MB_OK);
  668.  
  669.     hFile = OpenFile(NULL, &ofs, OF_REOPEN | OF_WRITE);
  670.     if (hFile==-1)
  671.         hFile = OpenFile(NULL, &ofs, OF_REOPEN | OF_CREATE | OF_WRITE);
  672.  
  673.     if (hFile==-1)
  674.         {
  675.         wsprintf(szBuf,"error: could not create the file %s",(LPSTR)ofs.szPathName);
  676.         MessageBox(hWnd,szBuf,APP_NAME,MB_OK);
  677.         }
  678.     else
  679.         {
  680.         SendMessage(hListBox,WM_SETREDRAW,0,0L);
  681.         n = (int) SendMessage(hListBox,LB_GETCOUNT,0,0L);
  682.         for (i=0; i<n; i++)
  683.             {
  684.             int len;
  685.             if (SendMessage(hListBox,LB_GETTEXTLEN,i,0L) > LINE_LENGTH)
  686.                 {
  687.                 MessageBox(hWnd,"line too long; skipping",APP_NAME,MB_OK);
  688.                 continue;
  689.                 }
  690.             SendMessage(hListBox,LB_GETTEXT,i,(LONG)(LPSTR)szBuf);
  691.             StripWhiteSpace(szBuf);
  692.             len = strlen(szBuf);
  693.             if (len==0) // MessageBox(hWnd,"error","error",MB_OK);
  694.                 continue;
  695.             while (len < LINE_LENGTH-2) szBuf[len++]=' ';
  696.             szBuf[len++]='\r';
  697.             szBuf[len]='\n';
  698.             write(hFile,szBuf,LINE_LENGTH);
  699. //DD(hListBox,">%s",szBuf);
  700.             }
  701. DD(hListBox,"done the write");
  702.         close(hFile);
  703.         SendMessage(hListBox,WM_SETREDRAW,1,0L);
  704.         return TRUE;
  705.         }
  706.     return FALSE;
  707. }
  708.  
  709.  
  710. /*SDOC*************************************************************
  711.  
  712.     Name: CopyComments
  713.  
  714.     Action: moves any comments from the edit box, stores it in the list
  715.             box
  716.         reads the comments from the current selection into the
  717.             edit box
  718.         the flush flag is used when we're changing the list box
  719.  
  720.     Returns: void
  721.  
  722. *************************************************************EDOC*/
  723. void CopyComments(HWND hListBox, HWND hEditBox)
  724. {
  725.     int     iNewSel;
  726.     static iOldSel=-1;
  727.     int    fDirtyTemp;
  728.  
  729.     iNewSel = (int) SendMessage(hListBox,LB_GETCURSEL,0,0L);
  730.          
  731.     if (fLocalDirty)
  732.         {
  733.         SendMessage(hListBox,WM_SETREDRAW,        0,0L);
  734.         SendMessage(hListBox,LB_GETTEXT,            iOldSel,(LONG)(LPSTR)szBuf);
  735.         SendMessage(hEditBox,WM_GETTEXT,            LINE_LENGTH-POS_COMMENTS,
  736.                                                             (LONG)(LPSTR)szBuf+POS_COMMENTS);
  737. DD(hEditBox,"sucked out the edit box <%s>",szBuf+POS_COMMENTS);
  738.         SendMessage(hListBox,LB_INSERTSTRING,    iOldSel,(LONG)(LPSTR)szBuf);
  739.         SendMessage(hListBox,WM_SETREDRAW,        1,0L);
  740.         SendMessage(hListBox,LB_DELETESTRING,    iOldSel+1,(LONG)(LPSTR)szBuf);
  741.         }
  742.  
  743.     SendMessage(hListBox,LB_GETTEXT,            max(iNewSel,0), (LONG)(LPSTR)szBuf);
  744.     StripWhiteSpace(szBuf);
  745.         // since setting the text will set the fDirty, push & pop it here
  746.     fDirtyTemp = fDirty;
  747.     SetWindowText(hEditBox,szBuf+POS_COMMENTS);
  748.     fDirty = fDirtyTemp;
  749.     SendMessage(hListBox,LB_SETCURSEL,        iNewSel,0L);
  750.     iOldSel = iNewSel;
  751.     fLocalDirty = FALSE;
  752. }
  753.  
  754.  
  755. /*SDOC*************************************************************
  756.  
  757.     Name: StripWhiteSpace
  758.  
  759.     Action: removes trailing white space and CR/LF
  760.  
  761.     Returns: the pointer to the string
  762.  
  763. *************************************************************EDOC*/
  764. char *StripWhiteSpace(char *str)
  765. {
  766.     char *p = str+strlen(str);
  767.     p--;
  768.     while (p>=str && isspace(*p)) *(p--)='\0';
  769.     return str;
  770. }
  771.  
  772. /*SDOC*************************************************************
  773.  
  774.     Name: NewDir
  775.  
  776.     Action: use the contents of the combo box to search to a new dir
  777.  
  778.     Returns: 
  779.  
  780. *************************************************************EDOC*/
  781. void NewDir(HWND hWnd,HWND hDirs)
  782. {
  783.     BOOL fDisk;
  784.     char    szTemp[_MAX_FNAME+_MAX_EXT];
  785.  
  786.     if (fDirty)
  787.         {
  788.         CopyComments(hListBox,hEditBox);
  789.         SaveFile(hWnd);
  790.         }
  791.     fDirty = fLocalDirty = FALSE;
  792.  
  793.     fDisk = DlgDirSelect(hWnd,szTemp,CDD_DIRS);
  794. DD(hWnd,"DlgDir returned <%s> %d",szTemp,fDisk);
  795.     if (szTemp[1]==':')
  796.         {
  797.         strcpy(szDrive,szTemp);
  798.         _getdcwd(toupper(szTemp[0])-'A'+1,szDir,_MAX_DIR);
  799.         strcpy(szDir,szDir+2);    //RISKY!!
  800. DD(hWnd,"using the drive %s path %s",szDrive,szDir);
  801.         }
  802.     else
  803.         strcat(szDir,szTemp);
  804.     _makepath(szBuf,szDrive,szDir,"*",".*");
  805.  
  806.     ParseAndFill(hWnd, szBuf);
  807.  
  808. }
  809. /*SDOC*************************************************************
  810.  
  811.     Name: ParseAndFill
  812.  
  813.     Action: reads a command line,
  814.         determines the notes file name,
  815.         fills the list box,
  816.         changes the window title bar,
  817.         fills the combo box,
  818.         and searches for the first file that matches the command line
  819.  
  820.     Returns: TRUE if everything went ok
  821.  
  822. *************************************************************EDOC*/
  823. BOOL ParseAndFill(HWND hWnd, LPSTR lpCmdLine)
  824. {
  825.  
  826. MessageBeep(5);
  827.         // parse the command line, find the notes file and match file
  828.     if (!CommandLine(lpCmdLine)) return FALSE;
  829. MessageBeep(5);
  830.  
  831.         // fill the list with real files, merge with old comments
  832.     FillListBox(hListBox);
  833. MessageBeep(5);
  834.  
  835.         // search for the match file
  836.     SearchForGivenFile(hListBox);
  837.  
  838.         // fill the edit box with comments on this file
  839.     CopyComments(hListBox,hEditBox);
  840.  
  841.         // prep the combo box
  842.     _makepath(szBuf,szDrive,szDir,"*",".*");
  843. DD(hWnd,"just made the new search dir for combo box");
  844. DD(hWnd,"      <%s>",szBuf);
  845.     DlgDirList(hWnd,szBuf,CDD_DIRS,CDD_PATH,0xC010);
  846.     SetFocus(hEditBox);
  847.  
  848.         // set the caption line
  849.     strcpy(szBuf,APP_NAME);
  850.     strcat(szBuf,": ");
  851.     strcat(szBuf,ofs.szPathName);
  852.     SetWindowText(hWnd,szBuf);
  853.  
  854.     return TRUE;
  855. }
  856.  
  857. /*SDOC*************************************************************
  858.  
  859.     Name: SearchForGivenFile
  860.  
  861.     Action: uses the global szFileName to search the list box
  862.         if it is found, the selection is set
  863.  
  864.     Returns: index of the file in the listbox
  865.  
  866. *************************************************************EDOC*/
  867. int    SearchForGivenFile(HWND hLB)
  868. {
  869.     int i=-1;
  870.  
  871.     if (*szFileName)
  872.         i = (int) SendMessage(hLB,LB_SELECTSTRING,-1,(LONG)(LPSTR)szFileName);
  873. DD(hLB,"search against <%s> returned %d",szFileName,i);
  874.     return i;
  875. }
  876.  
  877. /*SDOC*************************************************************
  878.  
  879.     Name: AboutBox
  880.  
  881.     Action: just displays the about box
  882.  
  883.     Returns: void
  884.  
  885. *************************************************************EDOC*/
  886. BOOL FAR PASCAL AboutBox(HWND hDlg, WORD message, WORD wParam, LONG lParam)
  887. {
  888.     lParam;
  889.     switch (message)
  890.         {
  891.         case WM_COMMAND:
  892.             if (wParam==IDOK)
  893.                 EndDialog(hDlg,TRUE);
  894.             break;
  895.         case WM_INITDIALOG:
  896.             break;
  897.         default:
  898.             return FALSE;
  899.         }
  900.     return TRUE;
  901. }
  902.  
  903.  
  904. /*SDOC*************************************************************
  905.  
  906.     Name: EditSubClassProc
  907.  
  908.     Action: traps any vertical key messages for the edit box, and
  909.         directs them to the list box
  910.         up, down, page up, page down, Ctrl PgUp and Ctrl PgDn
  911.  
  912.     Returns: the window proc
  913.  
  914. *************************************************************EDOC*/
  915. LONG FAR PASCAL EditSubClassProc(HWND hEdit, WORD message, WORD wParam, LONG lParam)
  916. {
  917.     if (message==WM_KEYDOWN || message==WM_KEYUP)
  918.         {
  919.         switch (wParam)
  920.             {
  921.             case VK_UP:
  922.             case VK_DOWN:
  923.             case VK_PRIOR:
  924.             case VK_NEXT:
  925.                 return SendMessage(hListBox,message,wParam,lParam);
  926.             }
  927.         }
  928.      return CallWindowProc(lpEditProc,hEdit,message,wParam,lParam);
  929. }
  930.  
  931.  
  932. /*SDOC*************************************************************
  933.  
  934.     Name: DirsSubClassProc
  935.  
  936.     Action: traps the enter key, and simulate a 
  937.         double click back to the parent
  938.  
  939.     Returns: the window proc
  940.  
  941. *************************************************************EDOC*/
  942. LONG FAR PASCAL DirsSubClassProc(HWND hDirs, WORD message, WORD wParam, LONG lParam)
  943. {
  944. DD(hDirs,"dirs box got message %x wParam %x, %lx",message,wParam,lParam);
  945.     switch (message)
  946.         {
  947.         case WM_KEYDOWN:
  948.             switch (wParam)
  949.                 {
  950.                 case VK_SPACE:
  951.                 case VK_RETURN:
  952.                     PostMessage(GetParent(hDirs),
  953.                             WM_COMMAND,
  954.                             CDD_DIRS,
  955.                             MAKELONG(hDirs,LBN_DBLCLK));
  956.                 }
  957.             break;
  958.         case WM_GETDLGCODE:
  959.             return (LONG) (DLGC_WANTCHARS |
  960.                     CallWindowProc(lpDirsProc,hDirs,message,wParam,lParam));
  961.         }
  962.      return CallWindowProc(lpDirsProc,hDirs,message,wParam,lParam);
  963. }
  964.