home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / winnt / netwatch / utils.c < prev    next >
C/C++ Source or Header  |  1995-06-13  |  17KB  |  805 lines

  1. /*
  2.  *  utils.c
  3.  *  
  4.  *  Purpose:
  5.  *      generic utils
  6.  *  
  7.  *  Owner:
  8.  *      MikeSart
  9.  */
  10. #define UNICODE 1
  11.  
  12. #include <windows.h>
  13. #include <windowsx.h>
  14. #include <commctrl.h>
  15. #include <time.h>
  16. #include <lm.h>
  17. #include "netwatch.h"
  18. #include "rcids.h"
  19.  
  20. ASSERTDATA
  21.  
  22. /*
  23.  *    General treeview routines
  24.  */
  25.  
  26. /*
  27.  *    FTreeView_GetString
  28.  *
  29.  *    Purpose:
  30.  *        Get the text from a treeview
  31.  *
  32.  *    Arguments:
  33.  *        hItem, szText, and cchText
  34.  *
  35.  *    Returns:
  36.  *        TRUE - success, FALSE - failure
  37.  */
  38. BOOL
  39. FTreeView_GetString(HWND hwndTV, HTREEITEM hItem, TCHAR *szText, UINT cchTextMax)
  40. {
  41.     TV_ITEM    tvItem;
  42.  
  43.     Assert(IsWindow(hwndTV) && hItem);
  44.     tvItem.mask = TVIF_TEXT;
  45.     tvItem.hItem = hItem;
  46.     tvItem.pszText = szText;
  47.     tvItem.cchTextMax = cchTextMax;
  48.     return TreeView_GetItem(hwndTV, &tvItem);
  49. }
  50.  
  51. /*
  52.  *    TreeView_GetRootCount
  53.  *
  54.  *    Purpose:
  55.  *        Count the number of roots (computers)
  56.  *
  57.  *    Arguments:
  58.  *        hwndTV
  59.  *
  60.  *    Returns:
  61.  *        a number
  62.  */
  63. UINT
  64. TreeView_GetRootCount(HWND hwndTV)
  65. {
  66.     HTREEITEM    hItem;
  67.     UINT        cRoots = 0;
  68.  
  69.     Assert(IsWindow(hwndTV));
  70.     hItem = TreeView_GetRoot(hwndTV);
  71.     while(hItem)
  72.     {
  73.         cRoots++;
  74.         hItem = TreeView_GetNextSibling(hwndTV, hItem);
  75.     }
  76.  
  77.     OutputDbgStr("TreeView_GetRootCount: %ld", cRoots);
  78.     return cRoots;
  79. }
  80.  
  81. /*
  82.  *    TreeView_GetRootList
  83.  *
  84.  *    Purpose:
  85.  *        Construct a REG_MULTI_SZ of roots
  86.  *
  87.  *    Arguments:
  88.  *        hwndTV, pcb
  89.  *
  90.  *    Returns:
  91.  *        TCHAR * to your new MULTI_SZ - be sure to free it
  92.  */
  93. LPTSTR
  94. TreeView_GetRootList(HWND hwndTV, DWORD *pcb)
  95. {
  96.     LPTSTR            pszT;
  97.     HTREEITEM        hItem;
  98.     LPTSTR            pszRootList;
  99.  
  100.     // Alloc enough for all the servers
  101.     Assert(IsWindow(hwndTV));
  102.     *pcb = (TreeView_GetRootCount(hwndTV) * (UNCLEN + 1) + 1) * sizeof(TCHAR);
  103.     pszRootList = GlobalAllocPtr(GHND, *pcb);
  104.     if(pszT = pszRootList)
  105.     {
  106.         hItem = TreeView_GetRoot(hwndTV);
  107.         while(hItem)
  108.         {
  109.             TV_ITEM    tvItem;
  110.             TCHAR    szT[UNCLEN + 1];
  111.  
  112.             // If we retrieved the text, save it
  113.             tvItem.mask = TVIF_TEXT | TVIF_IMAGE;
  114.             tvItem.hItem = hItem;
  115.             tvItem.pszText = szT;
  116.             tvItem.cchTextMax = UNCLEN + 1;
  117.             if(TreeView_GetItem(hwndTV, &tvItem) && (szT[0] == '\\'))
  118.             {
  119.                 // mark the first char as the image type
  120.                 szT[0] = tvItem.iImage + '0';
  121.                 // Make a REG_MULTI_SZ out of this stuff
  122.                 OutputDbgStr("Roots: '%ls'", szT);
  123.                 lstrcat(pszT, szT);
  124.                 pszT += lstrlen(szT) + 1;
  125.             }
  126.  
  127.             hItem = TreeView_GetNextSibling(hwndTV, hItem);
  128.         }
  129.     }
  130.  
  131.     return pszRootList;
  132. }
  133.  
  134. /*
  135.  *    GetComputerImage
  136.  *
  137.  *    Purpose:
  138.  *        Check the validity of a server the user is trying to add.
  139.  *
  140.  *    Arguments:
  141.  *        hwnd, szServerName
  142.  *
  143.  *    Returns:
  144.  *        -1 err, BMP_COMPUTER cool, BMP_COMPUTERLIMITED limited access
  145.  */
  146. int
  147. GetComputerImage(HWND hwnd, TCHAR *szServerName)
  148. {
  149.     NET_API_STATUS    nas;
  150.     TCHAR            chT;
  151.     HCURSOR            hCursor;
  152.     INT                iImage = -1;
  153.     SHARE_INFO_2    *shi2 = NULL;
  154.     DWORD            dwentriesread;
  155.     DWORD            dwtotalentries;
  156.     TCHAR            szMsg[cchErrMax];
  157.     TCHAR            *szErrMessage = NULL;
  158.  
  159.     Assert(hwnd);
  160.  
  161.     // When we write stuff to the registry, we set the first char to be the
  162.     // image type.
  163.     if((chT = szServerName[0]) != '\\')
  164.         szServerName[0] = '\\';
  165.  
  166.     // This may take a while
  167.     hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  168.  
  169.     CharUpper(szServerName);
  170.     nas = NetShareEnum(szServerName, 2, (LPBYTE *)&shi2,
  171.         MAX_PREFERRED_LENGTH, &dwentriesread, &dwtotalentries, NULL);
  172.     OutputDbgStr("GetComputerImage: nas = 0x%08lx", nas);
  173.  
  174.     SetCursor(hCursor);
  175.     switch(nas)
  176.     {
  177.         case ERROR_SUCCESS:
  178.             iImage = BMP_COMPUTER;
  179.             break;
  180.         case ERROR_ACCESS_DENIED:
  181.             wsprintf(szMsg, szFromIDS1(IDS_ERRACCESS), szServerName);
  182.             // If iImage is already BMP_COMPUTERLIMITED, then we must have
  183.             // restored this from the registry so don't ask the user again.
  184.             if((chT == ('0' + BMP_COMPUTERLIMITED)) ||
  185.                 MessageBox(hwnd, szMsg, szAppName,
  186.                 MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) == IDYES)
  187.                     iImage = BMP_COMPUTERLIMITED;
  188.             break;
  189.         default:
  190.             Assert(iImage == -1);
  191.             wsprintf(szMsg, szFromIDS1(IDS_ERRADDCOMPUTER), szServerName);
  192.             if(szErrMessage = GetSystemErrMessage(nas))
  193.                 lstrcat(szMsg, szErrMessage);
  194.             MessageBox(hwnd, szMsg, szAppName, MB_ICONEXCLAMATION | MB_OK);
  195.             break;
  196.     }
  197.  
  198.     GlobalFreeNullPtr(szErrMessage);
  199.     NetApiBufferFree(shi2);
  200.     return iImage;
  201. }
  202.  
  203. /*
  204.  *    hAddComputer
  205.  *
  206.  *    Purpose:
  207.  *        Add a new computer to the hwndTV
  208.  *
  209.  *    Arguments:
  210.  *        computername to add
  211.  *
  212.  *    Returns:
  213.  *        hItem of existing or new rooted computername
  214.  */
  215. HTREEITEM
  216. hAddComputer(HWND hwnd, HWND hwndTV, LPTSTR szComputerName,
  217.     HTREEITEM hItemLocation)
  218. {
  219.     TV_INSERTSTRUCT    tvis;
  220.     HTREEITEM        hItem;
  221.  
  222.     OutputDbgStr("hAddComputer: '%ls'", szComputerName);
  223.  
  224.     Assert(IsWindow(hwndTV));
  225.     // Check to see if the name already exists
  226.     hItem = TreeView_GetRoot(hwndTV);
  227.     while(hItem)
  228.     {
  229.         TCHAR        szT[UNCLEN + 1];
  230.  
  231.         if(FTreeView_GetString(hwndTV, hItem, szT, UNCLEN + 1) &&
  232.             !lstrcmpi(szComputerName, szT))
  233.         {
  234.             // Oooh - found one
  235.             OutputDbgStr("'%ls' already there", szComputerName);
  236.             TreeView_SelectItem(hwndTV, hItem);
  237.             return hItem;
  238.         }
  239.  
  240.         hItem = TreeView_GetNextSibling(hwndTV, hItem);
  241.     }
  242.  
  243.     // Not found - add it
  244.     // Check for access, computer existance, etc. here.
  245.     tvis.item.iImage = tvis.item.iSelectedImage =
  246.         GetComputerImage(hwnd, szComputerName);
  247.     if(tvis.item.iImage == -1)
  248.         return NULL;
  249.  
  250.     tvis.hParent = NULL;
  251.     tvis.hInsertAfter = hItemLocation;
  252.     tvis.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  253.     tvis.item.pszText = szComputerName;
  254.  
  255.     if(hItem = TreeView_InsertItem(hwndTV, &tvis))
  256.         TreeView_SelectItem(hwndTV, hItem);
  257.     return hItem;
  258. }
  259.  
  260. /*
  261.  *    RestoreServerList
  262.  *
  263.  *    Purpose:
  264.  *        add initial servers to tv via command line, registry, local computer
  265.  *
  266.  *    Arguments:
  267.  *        hwnd, hwndTV, REG_MULTI_SZ pszServers
  268.  *
  269.  *    Returns:
  270.  *        nada
  271.  */
  272. VOID
  273. RestoreServerList(HWND hwnd, HWND hwndTV, TCHAR *pszServers)
  274. {
  275.     DWORD        nT;
  276.     INT            argc;
  277.     LPTSTR        pszT;
  278.     HTREEITEM    hItem;
  279.     TCHAR        **argv;
  280.     BOOL        fSuccess = FALSE;
  281.     TCHAR        szComputerName[UNCLEN + 1];
  282.  
  283.     szComputerName[0] = szComputerName[1] = '\\';
  284.  
  285.     // Handle command line
  286.     argv = CommandLineToArgvW(GetCommandLine(), &argc);
  287.     while(argc-- > 1)
  288.     {
  289.         if(lstrlen(argv[argc]) > UNCLEN)
  290.             argv[argc][UNCLEN] = 0;
  291.  
  292.         nT = ((argv[argc][0] == '\\') && (argv[argc][1] == '\\')) ? 0 : 2;
  293.         lstrcpy(&szComputerName[nT], argv[argc]);
  294.         CharUpper(szComputerName);
  295.         if(hAddComputer(hwnd, hwndTV, szComputerName, TVI_FIRST))
  296.             fSuccess = TRUE;
  297.     }
  298.  
  299.     if(!fSuccess && pszServers)
  300.     {
  301.         // Loop through all these SZs adding em
  302.         for(pszT = pszServers; *pszT; pszT += lstrlen(pszT) + 1)
  303.         {
  304.             if(hAddComputer(hwnd, hwndTV, pszT, TVI_LAST))
  305.                 fSuccess = TRUE;
  306.             OutputDbgStr("Restoring '%ls'", pszT);
  307.         }
  308.     }
  309.  
  310.     // If we didn't get any servers yet, just default to this computer
  311.     if(!fSuccess)
  312.     {
  313.         nT = UNCLEN - 1;
  314.         Assert((szComputerName[0] == '\\') && (szComputerName[1] == '\\'));
  315.         if(GetComputerName(&szComputerName[2], &nT))
  316.             hAddComputer(hwnd, hwndTV, szComputerName, TVI_FIRST);
  317.     }
  318.  
  319.     // Select the first item
  320.     if(hItem = TreeView_GetRoot(hwndTV))
  321.         TreeView_SelectItem(hwndTV, hItem);
  322. }
  323.  
  324. /*
  325.  *    RestoreWindowPosition
  326.  *
  327.  *    Purpose:
  328.  *        Nostalgia
  329.  *
  330.  *    Arguments:
  331.  *        hwnd to nostalge
  332.  *
  333.  *    Returns:
  334.  *        zipola
  335.  */
  336. VOID
  337. RestoreWindowPosition(HWND hwnd, HWND hwndTV)
  338. {
  339.     DWORD            cb;
  340.     WINDOWPLACEMENT    wndpl;
  341.     DWORD            fHideTitle;
  342.     HKEY            hkey = NULL;
  343.     DWORD            dwTopMost = 0;
  344.     TCHAR            *pszServers = NULL;
  345.  
  346.     wndpl.showCmd = SW_SHOWNORMAL;
  347.     if(RegOpenKeyEx(HKEY_CURRENT_USER, szFromIDS1(IDS_KEY), 0, KEY_READ, &hkey))
  348.         goto err;
  349.  
  350.     cb = sizeof(fHideTitle);
  351.     if(!RegQueryValueEx(hkey, szFromIDS1(IDS_HIDETITLE), 0, 0,
  352.         (LPBYTE)&fHideTitle, &cb) && fHideTitle)
  353.             ShowTitle(hwnd, SW_HIDE);
  354.  
  355.     cb = COUNT_CHECKMENUS * sizeof(unMenuFlags[0]);
  356.     if(!RegQueryValueEx(hkey, szFromIDS1(IDS_MENUFLAGS), 0, 0,
  357.         (LPBYTE)unMenuFlags, &cb))
  358.     {
  359.         for(cb = 0; cb < COUNT_CHECKMENUS; cb++)
  360.         {
  361.             CheckMenuItem(ghMenu, CHECKMENUSTART + cb,
  362.                 MF_BYCOMMAND | unMenuFlags[cb]);
  363.         }
  364.     }
  365.  
  366.     cb = sizeof(wndpl);
  367.     if(!RegQueryValueEx(hkey, szFromIDS1(IDS_PLACEMENT), 0, 0,
  368.         (LPBYTE)&wndpl, &cb))
  369.     {
  370.         if(wndpl.length == sizeof(wndpl))
  371.             SetWindowPlacement(hwnd, &wndpl);
  372.     }
  373.  
  374.     cb = sizeof(dwTimerInterval);
  375.     RegQueryValueEx(hkey, szFromIDS1(IDS_TIMERINTERVAL), 0, 0,
  376.         (LPBYTE)&dwTimerInterval, &cb);
  377.  
  378.     if(!RegQueryValueEx(hkey, szFromIDS1(IDS_TOPMOST), 0, 0,
  379.         (LPBYTE)&dwTopMost, &cb) && cb && dwTopMost)
  380.     {
  381.         SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0,
  382.             SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  383.         CheckMenuItem(ghMenu, IDM_TOPMOST, MF_BYCOMMAND | MF_CHECKED);
  384.     }
  385.  
  386.     // Get the size of the servers and any we had store away.
  387.     cb = TreeView_GetCount(hwndTV);
  388.     if(!cb && !RegQueryValueEx(hkey, szFromIDS1(IDS_SERVERS), 0, 0, NULL, &cb))
  389.     {
  390.         if(cb && (pszServers = GlobalAllocPtr(GHND, cb)))
  391.             RegQueryValueEx(hkey, szFromIDS1(IDS_SERVERS), 0, 0,
  392.                 (LPBYTE)pszServers, &cb);
  393.     }
  394.  
  395.     CloseHandle(hkey);
  396.  
  397. err:
  398.     ShowWindow(hwnd, wndpl.showCmd);
  399.  
  400.     if(dwTimerInterval < 1000)
  401.         dwTimerInterval = 1000;
  402.  
  403.     RestoreServerList(hwnd, hwndTV, pszServers);
  404.     GlobalFreeNullPtr(pszServers);
  405. }
  406.  
  407. /*
  408.  *    SaveWindowPosition
  409.  *
  410.  *    Purpose:
  411.  *        Put all our eggs in one basket
  412.  *
  413.  *    Arguments:
  414.  *        hwnd of basket
  415.  *
  416.  *    Returns:
  417.  *        zipster
  418.  */
  419. VOID
  420. SaveWindowPosition(HWND hwnd, HWND hwndTV)
  421. {
  422.     DWORD            cb;
  423.     WINDOWPLACEMENT    wndpl;
  424.     HKEY            hkey;
  425.     DWORD            dwTopMost;
  426.     DWORD            fHideTitle;
  427.     LPTSTR            pszRootList;
  428.  
  429.     Assert(IsWindow(hwndTV));
  430.     wndpl.length = sizeof(wndpl);
  431.     GetWindowPlacement(hwnd, &wndpl);
  432.     // for some reason, GetWindowPlacement resets the length part??
  433.     wndpl.length = sizeof(wndpl);
  434.  
  435.     if(!RegCreateKeyEx(HKEY_CURRENT_USER, szFromIDS1(IDS_KEY), 0, szFromIDS1(IDS_KEY), 0,
  436.         KEY_READ | KEY_WRITE, 0, &hkey, NULL))
  437.     {
  438.         // Save away the list of computer names
  439.         if(pszRootList = TreeView_GetRootList(hwndTV, &cb))
  440.         {
  441.             RegSetValueEx(hkey, szFromIDS1(IDS_SERVERS), 0, REG_MULTI_SZ,
  442.                 (LPBYTE)pszRootList, cb);
  443.             GlobalFreePtr(pszRootList);
  444.         }
  445.  
  446.         RegSetValueEx(hkey, szFromIDS1(IDS_PLACEMENT), 0, REG_BINARY,
  447.             (LPBYTE)&wndpl, sizeof(wndpl));
  448.  
  449.         RegSetValueEx(hkey, szFromIDS1(IDS_MENUFLAGS), 0, REG_BINARY,
  450.             (LPBYTE)unMenuFlags, COUNT_CHECKMENUS * sizeof(unMenuFlags[0]));
  451.  
  452.         RegSetValueEx(hkey, szFromIDS1(IDS_TIMERINTERVAL), 0, REG_DWORD,
  453.             (LPBYTE)&dwTimerInterval, sizeof(dwTimerInterval));
  454.  
  455.         fHideTitle = GetMenu(hwnd) ? 0 : 1;
  456.         RegSetValueEx(hkey, szFromIDS1(IDS_HIDETITLE), 0, REG_DWORD,
  457.             (LPBYTE)&fHideTitle, sizeof(fHideTitle));
  458.  
  459.         dwTopMost = GetMenuState(ghMenu, IDM_TOPMOST, MF_BYCOMMAND) & MF_CHECKED;
  460.         RegSetValueEx(hkey, szFromIDS1(IDS_TOPMOST), 0, REG_DWORD,
  461.             (LPBYTE)&dwTopMost, sizeof(dwTopMost));
  462.  
  463.         CloseHandle(hkey);
  464.     }
  465. }
  466.  
  467. /*
  468.  *    szFromIDS1
  469.  *
  470.  *    Purpose:
  471.  *        LoadString and ids and keep it in a static buffer
  472.  *
  473.  *    Arguments:
  474.  *        ids to load
  475.  *
  476.  *    Returns:
  477.  *        TCHAR * to the static buffer
  478.  */
  479. TCHAR *
  480. szFromIDS1(UINT unID)
  481. {
  482. #define cchMaxIDS        200
  483.     static TCHAR szBuf1[cchMaxIDS];
  484.  
  485.     szBuf1[0] = '\0';
  486.     SideAssert(LoadString(ghInst, unID, szBuf1, cchMaxIDS));
  487.     return szBuf1;
  488. }
  489.  
  490. /*
  491.  *    AllocAndLoadString
  492.  *
  493.  *    Purpose:
  494.  *        Alloc enough room to load an IDS
  495.  *
  496.  *    Arguments:
  497.  *        ids to return
  498.  *
  499.  *    Returns:
  500.  *        TCHAR *
  501.  */
  502. TCHAR *
  503. AllocAndLoadString(UINT unID)
  504. {
  505.     TCHAR    *sz;
  506.     TCHAR    *szT = szFromIDS1(unID);
  507.  
  508.     sz = GlobalAllocPtr(GHND, (lstrlen(szT) + 1) * sizeof(TCHAR));
  509.     if(sz)
  510.         lstrcpy(sz, szT);
  511.  
  512.     return sz;
  513. }    
  514.  
  515. /*
  516.  *    GetSystemErrMessage
  517.  *
  518.  *    Purpose:
  519.  *        Format an error message string
  520.  *
  521.  *    Arguments:
  522.  *        dwError
  523.  *
  524.  *    Returns:
  525.  *        a TCHAR * that you must free
  526.  */
  527. TCHAR *
  528. GetSystemErrMessage(DWORD dwError)
  529. {
  530.     LPTSTR  szErrMessage = NULL;
  531.     HMODULE hLibrary;
  532.  
  533.     if(dwError == ERROR_INVALID_LEVEL)
  534.     {
  535.         // This err usually occurs when we try to view a WFW machine.
  536.         // So, the PM decided to use our own version of the err msg.
  537.         szErrMessage = AllocAndLoadString(IDS_ERRWFW);
  538.     } 
  539.     else if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  540.         NULL, dwError, 0, (LPTSTR)&szErrMessage, 0, NULL))
  541.     {
  542.         szErrMessage[lstrlen(szErrMessage) - 2] = '\0'; // remove /r/n
  543.     }
  544.     else if(hLibrary = LoadLibrary(MESSAGE_FILENAME))
  545.     {
  546.         if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE,
  547.             (LPVOID)hLibrary, dwError, 0, (LPTSTR)&szErrMessage, 0, NULL))
  548.         {
  549.             szErrMessage[lstrlen(szErrMessage) - 2] = '\0'; // remove /r/n
  550.         }
  551.         FreeLibrary(hLibrary);
  552.     }
  553.  
  554.     return szErrMessage;
  555. }
  556.  
  557. /*
  558.  *    PunchTimer
  559.  *
  560.  *    Purpose:
  561.  *        turn on\off timer
  562.  *
  563.  *    Arguments:
  564.  *        TRUE: turn on timer
  565.  *        FALSE: turn it off
  566.  *
  567.  *    Returns:
  568.  *        nada
  569.  */
  570. VOID
  571. PunchTimer(HWND hwndMain, BOOL fNewState)
  572. {
  573.     static BOOL fCurrentState = FALSE;
  574.  
  575.     if(fCurrentState == fNewState)
  576.         return;
  577.  
  578.     if(fNewState)
  579.         SetTimer(hwndMain, TIMERID, dwTimerInterval, NULL);
  580.     else
  581.         KillTimer(hwndMain, TIMERID);
  582.  
  583.     fCurrentState = fNewState;
  584. }
  585.  
  586. /*
  587.  *    ShowTitle
  588.  *
  589.  *    Purpose:
  590.  *        Show\Hidle title bar
  591.  *
  592.  *    Arguments:
  593.  *        hwnd, nCmdShow (SW_HIDE, SW_SHOW)
  594.  *
  595.  *    Returns:
  596.  *        zip
  597.  */
  598. VOID
  599. ShowTitle(HWND hwnd, int nCmdShow)
  600. {
  601.     DWORD            dwStyle;
  602.     static HMENU    hMenu = NULL;
  603.  
  604.     dwStyle = GetWindowLong(hwnd, GWL_STYLE);
  605.     if(hMenu)
  606.     {
  607.         dwStyle = WS_TILEDWINDOW | dwStyle;
  608.         SetMenu(hwnd, hMenu);
  609.         hMenu = NULL;
  610.     }
  611.     else
  612.     {
  613.         dwStyle &= ~(WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
  614.         hMenu = GetMenu(hwnd);
  615.         SetMenu(hwnd, NULL);
  616.     }
  617.  
  618.     SetWindowLong(hwnd, GWL_STYLE, dwStyle);
  619.     SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
  620.         SWP_NOZORDER | SWP_FRAMECHANGED);
  621.  
  622.     ShowWindow(hwnd, nCmdShow);
  623. }
  624.  
  625. /*
  626.  *    Date\Time routines
  627.  */
  628.  
  629. /*
  630.  *    PutDate
  631.  *
  632.  *    Purpose:
  633.  *        Convert a tm_t to '6/8/95'
  634.  *
  635.  *    Arguments:
  636.  *        tm_t, str, and cchstr
  637.  *
  638.  *    Returns:
  639.  *        str
  640.  */
  641. TCHAR *
  642. PutDate(time_t tm_t, TCHAR *szStr, UINT cch)
  643. {
  644.     SYSTEMTIME  st;
  645.     struct tm   *ptm;
  646.  
  647.     ptm = localtime(&tm_t);
  648.  
  649.     st.wYear    = ptm->tm_year + 1900;
  650.     st.wMonth    = ptm->tm_mon + 1;
  651.     st.wDay        = ptm->tm_mday;
  652.  
  653.     GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, szStr, cch);
  654.     return szStr;
  655. }
  656.  
  657. /*
  658.  *    PutTime
  659.  *
  660.  *    Purpose:
  661.  *        Convert a tm_t to '6:31 am'
  662.  *
  663.  *    Arguments:
  664.  *        tm_t, str, and cchstr
  665.  *
  666.  *    Returns:
  667.  *        str
  668.  */
  669. TCHAR *
  670. PutTime(time_t tm_t, TCHAR *szStr, UINT cch)
  671. {
  672.     SYSTEMTIME  st;
  673.     struct tm   *ptm;
  674.  
  675.     ptm = localtime(&tm_t);
  676.  
  677.     st.wHour            = ptm->tm_hour;
  678.     st.wMinute            = ptm->tm_min;
  679.     st.wSecond            = ptm->tm_sec;
  680.     st.wMilliseconds    = 0;
  681.  
  682.     GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, szStr, cch);
  683.     return szStr;
  684. }
  685.  
  686. /*
  687.  *    PutCounterTime
  688.  *
  689.  *    Purpose:
  690.  *        Convert a tm_t to '6:31:00'
  691.  *
  692.  *    Arguments:
  693.  *        tm_t, str, and cchstr
  694.  *
  695.  *    Returns:
  696.  *        str
  697.  */
  698. TCHAR *
  699. PutCounterTime(DWORD dwTime, TCHAR *szStr, UINT cch)
  700. {
  701.     SYSTEMTIME      st;
  702.     TCHAR            szTimeSep[cchSzMax];
  703.     SCONST TCHAR    szFmtCounter[] = TEXT("%02d%s%d");
  704.  
  705.     st.wHour            = (WORD)(dwTime / 3600);
  706.     dwTime                -= (st.wHour * 3600);
  707.     st.wMinute            = (WORD)(dwTime / 60);
  708.     dwTime                -= (st.wMinute * 60);
  709.     st.wSecond            = (WORD)dwTime;
  710.     st.wMilliseconds    = 0;
  711.  
  712.     GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIME, szTimeSep, cchSzMax);
  713.     wsprintf(szStr, szFmtCounter, st.wHour, szTimeSep, st.wMinute);
  714.     Assert((UINT)lstrlen(szStr) < cch);
  715.     return szStr;
  716. }
  717.  
  718. /*
  719.  *  TreeView and Imagelist routines
  720.  */
  721.  
  722. // handle to our imagelist
  723. HIMAGELIST    hImal = NULL;
  724.  
  725. /*
  726.  *  InitNetWatchWnd
  727.  *  
  728.  *  Purpose:
  729.  *      inits listbox globals, creates listbox
  730.  *  
  731.  *  Arguments:
  732.  *      HWND    main hwnd of app (parent of LB)
  733.  *  
  734.  *  Returns:
  735.  *      hwnd of treeview
  736.  */
  737. HWND
  738. InitNetWatchWnd(HWND hwnd)
  739. {
  740.     HWND            hwndTV;
  741.     SCONST TCHAR    szWCTreeView[] = WC_TREEVIEW;
  742.  
  743.     OutputDbgStr("InitNetWatchWnd");
  744.  
  745.     // Init common controls
  746.     InitCommonControls();
  747.  
  748.     // Create our imagelist
  749.     hImal = ImageList_LoadBitmap(ghInst, MAKEINTRESOURCE(IDB_LB),
  750.         BMWIDTH, 0, RGBREPLACE);
  751.     if(!hImal)
  752.         return NULL;
  753.  
  754.     // Create our treeview
  755.     hwndTV = CreateWindow(szWCTreeView, NULL,
  756.         WS_VISIBLE | WS_CHILD | TVS_HASLINES | TVS_DISABLEDRAGDROP,
  757.         0, 0, 0, 0, hwnd, (HMENU)IDD_tvwSHARES, ghInst, NULL);
  758.     if(!hwndTV)
  759.         return NULL;
  760.     TreeView_SetImageList(hwndTV, hImal, 0);
  761.  
  762.     // Make sure our new tv has the focus
  763.     SetFocus(hwndTV);
  764.     return hwndTV;
  765. }
  766.  
  767. /*
  768.  *  DeInitNetWatchWnd
  769.  *  
  770.  *  Purpose:
  771.  *      cleans up LB hfonts, hdc, and hbmps
  772.  *  
  773.  *  Arguments:
  774.  *  
  775.  *  Returns:
  776.  *      hopefully
  777.  */
  778. VOID
  779. DeInitNetWatchWnd(VOID)
  780. {
  781.     if(hImal)
  782.     {
  783.         ImageList_Destroy(hImal);
  784.         hImal = NULL;
  785.     }
  786. }
  787.  
  788. /*
  789.  *    BlitIcon
  790.  *
  791.  *    Purpose:
  792.  *        Smack an icon onto an hdc
  793.  *
  794.  *    Arguments:
  795.  *        hdc, x, y, bitmap index
  796.  *
  797.  *    Returns:
  798.  *        nope
  799.  */
  800. VOID
  801. BlitIcon(HDC hdc, LONG x, LONG y, int nBitmap)
  802. {
  803.     ImageList_Draw(hImal, nBitmap, hdc, x, y, ILD_TRANSPARENT);
  804. }
  805.