iconbar.c
上传用户:jlteech
上传日期:2007-01-06
资源大小:349k
文件大小:18k
源码类别:

压缩解压

开发平台:

Visual C++

  1. /*
  2.  Copyright (C) 1996 Mike White
  3.  Permission is granted to any individual or institution to use, copy, or
  4.  redistribute this software so long as all of the original files are included,
  5.  that it is not sold for profit, and that this copyright notice is retained.
  6. */
  7. #define STRICT
  8. #include <windows.h>
  9. #include <string.h>
  10. #include <commdlg.h>
  11. #include <stdio.h>
  12. #include <dos.h>
  13. #include <time.h>
  14. #include "wiz.h"
  15. #define DKGRAY_PEN      RGB(128, 128, 128)
  16. #define IB_SPACE        -1
  17. /* Forward declarations */
  18. void ButtonBar(HWND, LPBUTTON);
  19. void CreateButtonBar(HWND hWndParent);
  20. VOID SubClassButton (HWND hwnd, WNDPROC SubClassBtnProc);
  21. LRESULT CALLBACK SubClassBtnProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  22. static WNDPROC pfnOldProc;
  23. static BOOL first = FALSE;
  24. static HWND hHelpBtnWnd = NULL;
  25. HWND   hWndButtonBarOwner;
  26. HWND   hWndButtonBar;
  27. int    Width, Height;
  28. int    BtnSeparator = 1;
  29. float  BtnMult = (float)BTNWIDTH;
  30. BUTTON    Buttons[NUMOFBUTTONS + 1];
  31. LPBUTTON  lpIB;
  32. /*
  33.  *  function:  SubClassBtnProc
  34.  *
  35.  *  input parameters:  normal window procedure parameters.
  36.  *  global variables:
  37.  *   hWndButtonBar  - parent window of the control.
  38.  */
  39. LRESULT CALLBACK SubClassBtnProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  40. {
  41. RECT rc, rw;
  42. POINT p;
  43.   switch (message) {
  44.     case WM_MOUSEMOVE: {
  45.       int left, top;
  46.       POINT pt;
  47.       if (!uf.fShowBubbleHelp)
  48.          return 0;
  49.       p.x = LOWORD(lParam); /* Get mouse coordinates */
  50.       p.y = HIWORD(lParam);
  51.       for (lpIB = Buttons; lpIB->idBtn != 0; lpIB++)
  52.          {
  53.          if (lpIB->hWndBtn == hWnd)
  54.             {
  55.             if  (ChildWindowFromPoint(hWnd, p) != hWnd)
  56.                 {
  57.                 if (hHelpBtnWnd != NULL)
  58.                    {
  59.                    ShowCaret(hHelpBtnWnd);
  60.                    DestroyWindow(hHelpBtnWnd);
  61.                    }
  62.                 hHelpBtnWnd = NULL;
  63.                 if (GetCapture != NULL)
  64.                    ReleaseCapture();
  65.                 break; /* Mouse has moved off the button */
  66.                 }
  67.             if (GetCapture() != hWnd)
  68.                {
  69.                SetCapture(hWnd);
  70.                /* Convert left, right corners of button to hWndMain
  71.                   coordinates
  72.                 */
  73.                WinAssert(hWnd);
  74.                GetWindowRect(hWnd, &rc);
  75.                GetWindowRect(hWndMain, &rw);
  76.                if ((rc.left + ((lstrlen(lpIB->ButtonHelp)+1) * dxChar)) < rw.right)
  77.                   {
  78.                   pt.x = rc.left;
  79.                   pt.y = rc.top;
  80.                   ScreenToClient(hWndMain, &pt);
  81.                   left = pt.x;
  82.                   }
  83.                else
  84.                   {
  85.                   pt.x = rc.right;
  86.                   pt.y = rc.bottom;
  87.                   ScreenToClient(hWndMain, &pt);
  88.                   left = pt.x - ((lstrlen(lpIB->ButtonHelp)+1) * dxChar);
  89.                   }
  90.                pt.x = rc.right;
  91.                pt.y = rc.bottom;
  92.                ScreenToClient(hWndMain, &pt);
  93.                top = pt.y;
  94.                hHelpBtnWnd = CreateWindow("EDIT", NULL,
  95.                   WS_VISIBLE|ES_READONLY|WS_BORDER|WS_CHILD,
  96.                   left, top,
  97.                   (lstrlen(lpIB->ButtonHelp)+1) * dxChar, (int)(1.5 * dyChar),
  98.                   hWndMain,
  99.                   (HMENU) NULL,
  100.                   (HANDLE) hInst,
  101.                   NULL);
  102.                SendMessage(hHelpBtnWnd, WM_SETFONT, (WPARAM)hFixedFont, TRUE);
  103.                SendMessage(hHelpBtnWnd, WM_SETTEXT, 0, (LPARAM)lpIB->ButtonHelp);
  104.                HideCaret(hHelpBtnWnd);
  105.                break;
  106.               }
  107.             }
  108.          }
  109.       return 0;
  110.       }
  111.     /*
  112.      * For messages that are not handled explicitly, pass them on
  113.      * to the original window procedure.
  114.      */
  115.     default:
  116.       if (hHelpBtnWnd != NULL)
  117.          {
  118.          DestroyWindow(hHelpBtnWnd);
  119.          hHelpBtnWnd = NULL;
  120.          if (GetCapture() != NULL)
  121.             ReleaseCapture();
  122.          }
  123.       return (CallWindowProc ((pfnOldProc), hWnd, message, wParam, lParam));
  124.     } /* end switch */
  125. }
  126. /*
  127.  *  function:  SubClassButton
  128.  *
  129.  *  input parameters:
  130.  *     hwnd            - window handle to be subclassed,
  131.  *     SubClassBtnProc - the new window procedure.
  132.  *
  133.  *  Set in a new window procedure for this window.  Store the old window
  134.  *  procedure in the first field of the extrabytes structure.  This routine
  135.  *  is specific to this program in the use of this particular extrabyte
  136.  *  structure.  Note that the pointer to the user bytes needs to be freed
  137.  *  later (in WM_DESTROY).
  138.  */
  139. VOID SubClassButton (HWND hwnd, WNDPROC SubClassBtnProc)
  140. {
  141. WinAssert(hwnd);
  142. if (!first)
  143.    {
  144.    pfnOldProc = (WNDPROC) GetWindowLong (hwnd, GWL_WNDPROC);
  145.    first = TRUE;
  146.    }
  147. SetWindowLong (hwnd, GWL_WNDPROC,  (LONG) SubClassBtnProc);
  148. }
  149. /* WARNING If you add a button, you must change the #define in WIZ.H for
  150.    NUMOFBUTTONS. Any more buttons, and you might have trouble with VGA, or
  151.    640x480 display modes.
  152. */
  153. void CreateButtonBar(HWND hWndParent)
  154. {
  155. int i=0;
  156. /* WARNING: The order here MUST be the same order as is used down below
  157.    where handles are assigned to the various buttons, otherwise you will
  158.    get strange results as buttons are given different handles than intended.
  159.  */
  160. Buttons[i].idBtn     = IDM_ZIP_TARGET;
  161. Buttons[i].ButtonHelp = "Create/Update Archive";
  162. Buttons[i++].hBMP = "ARCHIVE_BUTTON";
  163. Buttons[i].idBtn     = IDM_OPEN;
  164. Buttons[i].ButtonHelp = "Open Archive";
  165. Buttons[i++].hBMP = "OPEN_BUTTON";
  166. Buttons[i].idBtn     = IDM_EXTRACT;
  167. Buttons[i].ButtonHelp = "Extract File(s) From Archive";
  168. Buttons[i++].hBMP = "EXTRACT_BUTTON";
  169. Buttons[i].idBtn     = IDM_CHDIR;
  170. Buttons[i].ButtonHelp = "Unzip To Directory";
  171. Buttons[i++].hBMP = "UNZIPTODIR_BUTTON";
  172. Buttons[i].idBtn     = IDM_SELECT_ALL;
  173. Buttons[i].ButtonHelp = "Select All Files";
  174. Buttons[i++].hBMP = "SELECTALL_BUTTON";
  175. Buttons[i].idBtn     = IDM_DESELECT_ALL;
  176. Buttons[i].ButtonHelp = "De-Select All Files";
  177. Buttons[i++].hBMP = "DESELECTALL_BUTTON";
  178. Buttons[i].idBtn     = IDM_SELECT_BY_PATTERN;
  179. Buttons[i].ButtonHelp = "Select Files By Pattern";
  180. Buttons[i++].hBMP = "SELECTPATTERN_BUTTON";
  181. #ifdef MAX_BUTTONS
  182. Buttons[i].idBtn     = IDM_DISPLAY;
  183. Buttons[i].ButtonHelp = "Display File From Archive";
  184. Buttons[i++].hBMP = "DISPLAY_BUTTON";
  185. Buttons[i].idBtn     = IDM_TEST;
  186. Buttons[i].ButtonHelp = "Test Archive";
  187. Buttons[i++].hBMP = "TEST_BUTTON";
  188. Buttons[i].idBtn     = IDM_GET_ZIPINFO;
  189. Buttons[i].ButtonHelp = "Get Zip Information";
  190. Buttons[i++].hBMP = "GET_ZIPINFO_BUTTON";
  191. Buttons[i].idBtn     = IDM_SHOW_COMMENT;
  192. Buttons[i].ButtonHelp = "Show Comment";
  193. Buttons[i++].hBMP = "COMMENT_BUTTON";
  194. Buttons[i].idBtn     = IDM_COPY_ARCHIVE;
  195. Buttons[i].ButtonHelp = "Copy Archive";
  196. Buttons[i++].hBMP = "COPY_BUTTON";
  197. Buttons[i].idBtn     = IDM_MOVE_ARCHIVE;
  198. Buttons[i].ButtonHelp = "Move Archive";
  199. Buttons[i++].hBMP = "MOVE_BUTTON";
  200. Buttons[i].idBtn     = IDM_RENAME_ARCHIVE;
  201. Buttons[i].ButtonHelp = "Rename Archive";
  202. Buttons[i++].hBMP = "RENAME_BUTTON";
  203. Buttons[i].idBtn     = IDM_MAKE_DIR;
  204. Buttons[i].ButtonHelp = "Make Directory";
  205. Buttons[i++].hBMP = "MAKEDIR_BUTTON";
  206. #endif
  207. Buttons[i].idBtn     = IDM_DELETE_ARCHIVE;
  208. Buttons[i].ButtonHelp = "Delete Archive";
  209. Buttons[i++].hBMP = "DELETE_BUTTON";
  210. Buttons[i].idBtn     = IDM_CLEAR_STATUS;
  211. Buttons[i].ButtonHelp = "Clear Status/Display Window";
  212. Buttons[i++].hBMP = "CLEARSTATUS_BUTTON";
  213. Buttons[i].idBtn     = IDM_STATUS;
  214. Buttons[i].ButtonHelp = "Hide Edit/Status Window";
  215. Buttons[i++].hBMP = "STATUS_BUTTON";
  216. Buttons[i].idBtn     = IDM_EXIT;
  217. Buttons[i].ButtonHelp = "Exit WiZ";
  218. Buttons[i++].hBMP = "EXIT_BUTTON";
  219. Buttons[i].idBtn     = IDM_HELP;
  220. Buttons[i].ButtonHelp = "WiZ Help";
  221. Buttons[i++].hBMP = "HELP_BUTTON";
  222. Buttons[i].idBtn     = 0;
  223. Buttons[i].ButtonHelp = NULL;
  224. Buttons[i].hWndBtn   = NULL;
  225. ButtonBar(hWndParent, Buttons);
  226. return;
  227. }
  228. void ButtonBar(HWND hWndParent, LPBUTTON lpButton)
  229. {
  230. int          i, x;
  231. RECT         rect;
  232. hWndButtonBarOwner  = hWndParent;
  233. WinAssert(hWndParent);
  234. GetWindowRect(hWndParent, &rect);
  235. hWndButtonBar = CreateWindow("ButtonBar", NULL,
  236.         WS_VISIBLE | WS_CLIPSIBLINGS |WS_DLGFRAME| WS_CHILD,
  237.         0, 0,
  238.         rect.right - rect.left,
  239.         (int)(2.1 * dyChar),
  240.         hWndButtonBarOwner,
  241.         (HMENU) NULL,
  242.         (HINSTANCE) hInst,
  243.         NULL);
  244. WinAssert(hWndButtonBar);
  245. ShowWindow(hWndButtonBar, SW_SHOW);
  246. GetClientRect(hWndButtonBar, &rect);
  247. Height = rect.bottom;
  248. BtnSeparator = 1;   /* Set distance between buttons back to 1 */
  249. BtnMult = (float)BTNWIDTH; /* Reset multiplier to original setting */
  250. Width = (int)(BtnMult*dxChar);
  251. WinAssert(hWndParent);
  252. #ifdef RESIZE_BUTTONS
  253. GetClientRect(hWndParent, &rect);
  254. if (((Width * NUMOFBUTTONS) + NUMOFBUTTONS) > rect.right)
  255.    {
  256.    while (BtnMult > MIN_BTN_WIDTH)
  257.       {
  258.       BtnMult = (float)(BtnMult - 0.1);
  259.       Width = (int)(BtnMult*dxChar);
  260.       if (((Width * NUMOFBUTTONS) + NUMOFBUTTONS) < rect.right)
  261.          continue;
  262.       }
  263.    }
  264. /* Last ditch effort to get all the buttons on the screen */
  265. if (((Width * NUMOFBUTTONS) + NUMOFBUTTONS) > rect.right)
  266.    {
  267.    BtnSeparator = 0;
  268.    }
  269. #endif
  270. x = BtnSeparator;
  271. for (lpIB = lpButton; lpIB->idBtn != 0; lpIB++)
  272.     {
  273.     if (lpIB->idBtn == -1)
  274.        continue;
  275.     (lpIB->hWndBtn) = CreateWindow("BUTTON", "",
  276.                       WS_VISIBLE | BS_OWNERDRAW | WS_CHILD,
  277.                       x, 0,
  278.                       Width, Height,
  279.                       hWndButtonBar,
  280.                       (HMENU) lpIB->idBtn, (HINSTANCE) hInst, NULL );
  281.     SubClassButton (lpIB->hWndBtn, SubClassBtnProc);
  282.     x += Width + BtnSeparator;
  283.     }
  284. /* WARNING: The order here MUST be the same order as is used above
  285.    where the various buttons are created, otherwise you will
  286.    get strange results as buttons are given different handles than
  287.    intended.
  288.  */
  289. i = 0;
  290. hArchive       = Buttons[i++].hWndBtn;
  291. hOpen          = Buttons[i++].hWndBtn;
  292. hExtract       = Buttons[i++].hWndBtn;
  293. hUnzipToDir    = Buttons[i++].hWndBtn;
  294. hSelectAll     = Buttons[i++].hWndBtn;
  295. hDeselectAll   = Buttons[i++].hWndBtn;
  296. hSelectPattern = Buttons[i++].hWndBtn;
  297. #ifdef MAX_BUTTONS
  298. hDisplay       = Buttons[i++].hWndBtn;
  299. hTest          = Buttons[i++].hWndBtn;
  300. hZipInfo       = Buttons[i++].hWndBtn;
  301. hShowComment   = Buttons[i++].hWndBtn;
  302. hCopyArchive   = Buttons[i++].hWndBtn;
  303. hMoveArchive   = Buttons[i++].hWndBtn;
  304. hRenameArchive = Buttons[i++].hWndBtn;
  305. hMakeDir       = Buttons[i++].hWndBtn;
  306. #endif
  307. hDeleteArchive = Buttons[i++].hWndBtn;
  308. hClearStatus   = Buttons[i++].hWndBtn;
  309. hStatusButton  = Buttons[i++].hWndBtn;
  310. hExit          = Buttons[i++].hWndBtn;
  311. hHelp          = Buttons[i].hWndBtn;
  312. return;
  313. }
  314. void MoveButtons(void)
  315. {
  316. int x = BtnSeparator;
  317. for (lpIB = Buttons; lpIB->idBtn != 0; lpIB++)
  318.     {
  319.     WinAssert(lpIB->hWndBtn);
  320.     MoveWindow(lpIB->hWndBtn, x, 0, Width, Height, FALSE);
  321.     x += Width + BtnSeparator;
  322.     }
  323. }
  324. LRESULT WINAPI ButtonBarWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  325. {
  326. HPEN             hPen, hOldPen;
  327. HBRUSH           hBrush;
  328. LPDRAWITEMSTRUCT lpdis;
  329. HDC              hdcMem;
  330. HBITMAP          hBitmap;
  331. long             flag;
  332. int              i;
  333. switch(message)
  334.    {
  335.    case WM_COMMAND:
  336.         SendMessage(hWndButtonBarOwner, message, wParam, lParam);
  337.         return(FALSE);
  338.    case WM_DRAWITEM:
  339.         lpdis = (LPDRAWITEMSTRUCT) lParam;
  340.         lpIB = Buttons;
  341.         for (i=0;;i++)
  342.            {
  343.            if (lpIB[i].idBtn == 0)
  344.                return (FALSE); /* Not one of our controls */
  345.            if (lpIB[i].idBtn == (signed int)lpdis->CtlID)
  346.                break;          /* Found the right control */
  347.            }
  348.         if (lpIB[i].idBtn == IDM_STATUS)
  349.            {
  350.            if (!lstrcmp(lpIB[i].hBMP, "STATUS_BUTTON"))
  351.               {
  352.               lpIB[i].ButtonHelp = "Hide Edit/Status Window";
  353.               lpIB[i].hBMP = "LTSTATUS_BUTTON";
  354.               ModifyMenu(hMenu, IDM_MAX_STATUS, MF_BYCOMMAND |
  355.                  MF_ENABLED, IDM_MAX_STATUS,
  356.                  "Hide Edit/Status Window");
  357.               /* If we do a ShowWindow(hWndStatic, SW_SHOWNA) (which is what
  358.                  you would expect to do), if you hide, then unhide the status
  359.                  window, then minimize the main application, the status
  360.                  window will remain up. Hence this little tap dance here.
  361.                */  
  362.               ShowWindow(hWndStatic, SW_SHOW);
  363.               SetActiveWindow(hWndMain);
  364.               }
  365.            else
  366.               {
  367.               lpIB[i].ButtonHelp = "Show Edit/Status Window";
  368.               lpIB[i].hBMP = "STATUS_BUTTON";
  369.               ModifyMenu(hMenu, IDM_MAX_STATUS, MF_BYCOMMAND |
  370.                  MF_ENABLED, IDM_MAX_STATUS,
  371.                  "Show Edit/Status Window");
  372.               ShowWindow(hWndStatic, SW_HIDE);
  373.               }
  374.            }
  375.         lpdis->rcItem.right = Width;
  376.         lpdis->rcItem.bottom = Height;
  377.         lpdis->rcItem.right--;
  378.         lpdis->rcItem.bottom--;
  379.         hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU));
  380.         FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
  381.         DeleteObject(hBrush);
  382.         hOldPen = SelectObject(lpdis->hDC, GetStockObject(BLACK_PEN));
  383.         MoveToEx(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top, NULL);
  384.         LineTo(lpdis->hDC,lpdis->rcItem.right,lpdis->rcItem.top);
  385.         LineTo(lpdis->hDC,lpdis->rcItem.right,lpdis->rcItem.bottom);
  386.         LineTo(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.bottom);
  387.         LineTo(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top);
  388.         SelectObject(lpdis->hDC, hOldPen);
  389.         lpdis->rcItem.left++;
  390.         lpdis->rcItem.right--;
  391.         lpdis->rcItem.top++;
  392.         lpdis->rcItem.bottom--;
  393.         if (!IsWindowEnabled(lpIB[i].hWndBtn))
  394.            {
  395.            flag = SRCINVERT;  /* "Gray" out button */
  396.            }
  397.         else
  398.            {
  399.            flag = SRCCOPY;
  400.            }
  401.         if (lpdis->itemState & ODS_SELECTED)
  402.            {
  403.            /* Button has been depressed - make it look depressed */
  404.            hPen = CreatePen(PS_SOLID, 1, DKGRAY_PEN);
  405.            hOldPen = SelectObject(lpdis->hDC, hPen);
  406.            MoveToEx(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.bottom,NULL);
  407.            LineTo(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top);
  408.            LineTo(lpdis->hDC, lpdis->rcItem.right, lpdis->rcItem.top);
  409.            SelectObject(lpdis->hDC, hOldPen);
  410.            DeleteObject(hPen);
  411.            hdcMem = CreateCompatibleDC(lpdis->hDC);
  412.            hBitmap = LoadBitmap(hInst, lpIB[i].hBMP);
  413.            hOldPen = SelectObject(hdcMem, hBitmap);
  414.            StretchBlt(lpdis->hDC,   /* device to be drawn */
  415.               lpdis->rcItem.left+2, /* x upper left destination */
  416.               lpdis->rcItem.top+2,  /* y upper left destination */
  417.               lpdis->rcItem.right - lpdis->rcItem.left -2, /* width */
  418.               lpdis->rcItem.bottom - lpdis->rcItem.top - 2,/* height */
  419.               hdcMem, /* source bitmap */
  420.               0,      /* x upper left source */
  421.               0,      /* y upper left source */
  422.               32,     /* source bitmap width */
  423.               32,     /* source bitmap height */
  424.               flag);
  425.            SelectObject(hdcMem, hOldPen);
  426.            DeleteDC(hdcMem);
  427.            DeleteObject(hBitmap);
  428.            }
  429.         else
  430.            {
  431.            if (lpIB[i].idBtn == IDM_STATUS)
  432.               {
  433.               if (!lstrcmp(lpIB[i].hBMP, "STATUS_BUTTON"))
  434.                  lpIB[i].hBMP = "LTSTATUS_BUTTON";
  435.               else
  436.                  lpIB[i].hBMP = "STATUS_BUTTON";
  437.               }
  438.            /* Draw button */
  439.            hOldPen = SelectObject(lpdis->hDC, GetStockObject(WHITE_PEN));
  440.            MoveToEx(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.bottom,NULL);
  441.            LineTo(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top);
  442.            LineTo(lpdis->hDC,lpdis->rcItem.right,lpdis->rcItem.top);
  443.            SelectObject(lpdis->hDC, hOldPen);
  444.            hPen = CreatePen(PS_SOLID, 1, DKGRAY_PEN);
  445.            hOldPen = SelectObject(lpdis->hDC, hPen);
  446.            MoveToEx(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.bottom,NULL);
  447.            LineTo(lpdis->hDC,lpdis->rcItem.right,lpdis->rcItem.bottom);
  448.            LineTo(lpdis->hDC,lpdis->rcItem.right,lpdis->rcItem.top);
  449.            SelectObject(lpdis->hDC, hOldPen);
  450.            DeleteObject(hPen);
  451.            hdcMem = CreateCompatibleDC(lpdis->hDC);
  452.            hBitmap = LoadBitmap(hInst, lpIB[i].hBMP);
  453.            hOldPen = SelectObject(hdcMem, hBitmap);
  454.            StretchBlt(lpdis->hDC,
  455.               lpdis->rcItem.left+2,
  456.               lpdis->rcItem.top+2,
  457.               lpdis->rcItem.right - lpdis->rcItem.left -2,
  458.               lpdis->rcItem.bottom - lpdis->rcItem.top - 2,
  459.               hdcMem,
  460.               0,
  461.               0,
  462.               32,
  463.               32,
  464.               flag); /* This flag makes it look either enabled or greyed */
  465.            SelectObject(hdcMem, hOldPen);
  466.            DeleteDC(hdcMem);
  467.            DeleteObject(hBitmap);
  468.            }
  469.         return TRUE;
  470. /* This section draws a line around the button bar to highlight. It was decided
  471.    to take this out from the application, but the code is left here for those
  472.    who want this feature.
  473.            
  474.    case WM_PAINT:
  475.         {
  476.         RECT             rect;
  477.         PAINTSTRUCT      ps;
  478.         
  479.         BeginPaint(hWnd, &ps);
  480.         WinAssert(hWnd);
  481.         GetClientRect(hWnd, &rect);
  482.         hOldPen = SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
  483.         MoveToEx(ps.hdc, rect.left, rect.top, NULL);
  484.         LineTo(ps.hdc, rect.right+1, rect.top);
  485.         SelectObject(ps.hdc, hOldPen);
  486.         hPen = CreatePen(PS_SOLID, 1, DKGRAY_PEN);
  487.         hOldPen = SelectObject(ps.hdc, hPen);
  488.         MoveToEx(ps.hdc, rect.left, rect.bottom-2, NULL);
  489.         LineTo(ps.hdc, rect.right+1, rect.bottom-2);
  490.         SelectObject(ps.hdc, hOldPen);
  491.         DeleteObject(hPen);
  492.         hPen = CreatePen( PS_SOLID, 1, BLACK_PEN);
  493.         hOldPen = SelectObject(ps.hdc, hPen);
  494.         MoveToEx(ps.hdc, rect.left, rect.bottom-1, NULL);
  495.         LineTo(ps.hdc, rect.right+1, rect.bottom-1);
  496.         SelectObject(ps.hdc, hOldPen);
  497.         DeleteObject(hPen);
  498.         EndPaint(hWnd, &ps);
  499.         return (FALSE);
  500.         }
  501. */
  502.    default:
  503.       return(DefWindowProc(hWnd, message, wParam, lParam));
  504.    }
  505. }