DIALOGS.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:21k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*************************************************************************
  2. **
  3. **    OLE 2 Sample Code
  4. **
  5. **    dialogs.c
  6. **
  7. **    This file contains dialog functions and support function
  8. **
  9. **    (c) Copyright Microsoft Corp. 1992 - 1996 All Rights Reserved
  10. **
  11. *************************************************************************/
  12. #include "outline.h"
  13. OLEDBGDATA
  14. extern LPOUTLINEAPP g_lpApp;
  15. static OLECHAR  g_szBuf[MAXSTRLEN+1];
  16. static LPSTR g_lpszDlgTitle;
  17. // REVIEW: should use string resource for messages
  18. static OLECHAR ErrMsgInvalidRange[] = OLESTR("Invalid Range entered!");
  19. static OLECHAR ErrMsgInvalidValue[] = OLESTR("Invalid Value entered!");
  20. static OLECHAR ErrMsgInvalidName[] = OLESTR("Invalid Name entered!");
  21. static OLECHAR ErrMsgNullName[] = OLESTR("NULL string disallowed!");
  22. static OLECHAR ErrMsgNameNotFound[] = OLESTR("Name doesn't exist!");
  23. /* InputTextDlg
  24.  * ------------
  25.  *
  26.  *      Put up a dialog box to allow the user to edit text
  27.  */
  28. BOOL InputTextDlg(HWND hWnd, LPSTR lpszText, LPSTR lpszDlgTitle)
  29. {
  30.    int nResult;
  31.    g_lpszDlgTitle = lpszDlgTitle;
  32.    A2W (lpszText, g_szBuf, MAXSTRLEN+1);  // preload dialog with input text
  33.    nResult = DialogBox(g_lpApp->m_hInst, (LPSTR)"AddEditLine", hWnd,
  34.                   (DLGPROC)AddEditDlgProc);
  35.    if (nResult) {
  36.       W2A(g_szBuf, lpszText, MAXSTRLEN+1);
  37.       return TRUE;
  38.    } else {
  39.       return FALSE;
  40.    }
  41. }
  42. /* AddEditDlgProc
  43.  * --------------
  44.  *
  45.  * This procedure is associated with the dialog box that is included in
  46.  * the function name of the procedure. It provides the service routines
  47.  * for the events (messages) that occur because the end user operates
  48.  * one of the dialog box's buttons, entry fields, or controls.
  49.  */
  50. BOOL CALLBACK EXPORT AddEditDlgProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
  51. {
  52.    HWND hEdit;
  53.    char szAnsiString[256];
  54.    switch(Message) {
  55.       case WM_INITDIALOG:
  56.          /* initialize working variables */
  57.          hEdit=GetDlgItem(hDlg,IDD_EDIT);
  58.          SendMessage(hEdit,EM_LIMITTEXT,(WPARAM)MAXSTRLEN,0L);
  59.          SetWindowText(hDlg, g_lpszDlgTitle);
  60.          W2A (g_szBuf, szAnsiString, 256);
  61.          SetDlgItemText(hDlg,IDD_EDIT, szAnsiString);
  62.          break; /* End of WM_INITDIALOG */
  63.       case WM_CLOSE:
  64.          /* Closing the Dialog behaves the same as Cancel */
  65.          PostMessage(hDlg, WM_COMMAND, IDCANCEL, 0L);
  66.          break; /* End of WM_CLOSE */
  67.       case WM_COMMAND:
  68.          switch (wParam) {
  69.             case IDOK:
  70.                /* save data values entered into the controls
  71.                ** and dismiss the dialog box returning TRUE
  72.                */
  73.                GetDlgItemText(hDlg,IDD_EDIT,(LPSTR)g_szBuf,MAXSTRLEN+1);
  74.                EndDialog(hDlg, TRUE);
  75.                break;
  76.             case IDCANCEL:
  77.                /* ignore data values entered into the controls
  78.                ** and dismiss the dialog box returning FALSE
  79.                */
  80.                EndDialog(hDlg, FALSE);
  81.                break;
  82.          }
  83.          break;    /* End of WM_COMMAND */
  84.       default:
  85.          return FALSE;
  86.    }
  87.    return TRUE;
  88. } /* End of AddEditDlgProc */
  89. /* SetLineHeightDlgProc
  90.  * --------------------
  91.  *
  92.  *      Dialog procedure for set line height
  93.  */
  94. BOOL CALLBACK EXPORT SetLineHeightDlgProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
  95. {
  96.    BOOL    fTranslated;
  97.    BOOL    fEnable;
  98.    static LPINT    lpint;
  99.    int     nHeight;
  100.    static int nMaxHeight;
  101.    switch (Message) {
  102.       case WM_INITDIALOG:
  103.       {
  104.          char cBuf[80];
  105.          nMaxHeight = XformHeightInPixelsToHimetric(NULL,
  106.                         LISTBOX_HEIGHT_LIMIT);
  107.          lpint = (LPINT)lParam;
  108.          SetDlgItemInt(hDlg, IDD_EDIT, *lpint, FALSE);
  109.          wsprintf(cBuf, "Maximum value is %d units", nMaxHeight);
  110.          SetDlgItemText(hDlg, IDD_LIMIT, (LPSTR)cBuf);
  111.          break;
  112.       }
  113.       case WM_COMMAND:
  114.          switch (wParam) {
  115.             case IDOK:
  116.                if (IsDlgButtonChecked(hDlg, IDD_CHECK)) {
  117.                   *lpint = -1;
  118.                }
  119.                else {
  120.                   /* save the value in the edit control */
  121.                   nHeight = GetDlgItemInt(hDlg, IDD_EDIT,
  122.                         (BOOL FAR*)&fTranslated, FALSE);
  123.                   if (!fTranslated || !nHeight || (nHeight>nMaxHeight)){
  124.                      OutlineApp_ErrorMessage(g_lpApp,
  125.                            ErrMsgInvalidValue);
  126.                      break;
  127.                   }
  128.                   *lpint = nHeight;
  129.                }
  130.                EndDialog(hDlg, TRUE);
  131.                break;
  132.             case IDCANCEL:
  133.                *lpint = 0;
  134.                EndDialog(hDlg, FALSE);
  135.                break;
  136.             case IDD_CHECK:
  137.                fEnable = !IsDlgButtonChecked(hDlg, IDD_CHECK);
  138.                EnableWindow(GetDlgItem(hDlg, IDD_EDIT), fEnable);
  139.                EnableWindow(GetDlgItem(hDlg, IDD_TEXT), fEnable);
  140.                break;
  141.          }
  142.          break;  /* WM_COMMAND */
  143.       case WM_CLOSE:  /* Closing the Dialog behaves the same as Cancel */
  144.          PostMessage(hDlg, WM_COMMAND, IDCANCEL, 0L);
  145.          break; /* End of WM_CLOSE */
  146.       default:
  147.          return FALSE;
  148.    }
  149.    return TRUE;
  150. } /* end of SetLineHeightProc */
  151. /* DefineNameDlgProc
  152.  * -----------------
  153.  *
  154.  *      Dialog procedure for define name
  155.  */
  156. BOOL CALLBACK EXPORT DefineNameDlgProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
  157. {
  158.    static HWND hCombo;
  159.    static LPOUTLINEDOC lpOutlineDoc = NULL;
  160.    static LPOUTLINENAMETABLE lpOutlineNameTable = NULL;
  161.    LPOUTLINENAME lpOutlineName = NULL;
  162.    UINT nIndex;
  163.    LINERANGE lrSel;
  164.    BOOL fTranslated;
  165.    char szAnsiString[256];
  166.    switch(Message) {
  167.       case WM_INITDIALOG:
  168.       /* initialize working variables */
  169.          hCombo=GetDlgItem(hDlg,IDD_COMBO);
  170.          lpOutlineDoc = (LPOUTLINEDOC) lParam;
  171.          lpOutlineNameTable = OutlineDoc_GetNameTable(lpOutlineDoc);
  172.          SendMessage(hCombo,CB_LIMITTEXT,(WPARAM)MAXNAMESIZE,0L);
  173.          NameDlg_LoadComboBox(lpOutlineNameTable, hCombo);
  174.          OutlineDoc_GetSel(lpOutlineDoc, (LPLINERANGE)&lrSel);
  175.          lpOutlineName = OutlineNameTable_FindNamedRange(
  176.                lpOutlineNameTable,
  177.                &lrSel
  178.          );
  179.          /* if current selection already has a name, hilight it */
  180.          if (lpOutlineName) {
  181.             nIndex = (int) SendMessage(
  182.                   hCombo,
  183.                   CB_FINDSTRINGEXACT,
  184.                   (WPARAM)0xffff,
  185.                   (LPARAM)(LPCSTR)lpOutlineName->m_szName
  186.             );
  187.             if (nIndex != CB_ERR) {
  188.                SendMessage(hCombo, CB_SETCURSEL, (WPARAM)nIndex, 0L);
  189.             }
  190.          }
  191.          SetDlgItemInt(hDlg, IDD_FROM, (UINT)lrSel.m_nStartLine+1,FALSE);
  192.          SetDlgItemInt(hDlg, IDD_TO, (UINT)lrSel.m_nEndLine+1, FALSE);
  193.          break; /* End of WM_INITDIALOG */
  194.       case WM_CLOSE:
  195.       /* Closing the Dialog behaves the same as Cancel */
  196.          PostMessage(hDlg, WM_COMMAND, IDD_CLOSE, 0L);
  197.          break; /* End of WM_CLOSE */
  198.       case WM_COMMAND:
  199.          switch(wParam) {
  200.             case IDOK:
  201.                GetDlgItemText(hDlg,IDD_COMBO,(LPSTR)g_szBuf,MAXNAMESIZE);
  202.                if(! SendMessage(hCombo,WM_GETTEXTLENGTH,0,0L)) {
  203.                   W2A (ErrMsgNullName, szAnsiString, 256);
  204.                   MessageBox(
  205.                         hDlg,
  206.                         szAnsiString,
  207.                         NULL,
  208.                         MB_ICONEXCLAMATION
  209.                   );
  210.                   break;
  211.                } else if(SendMessage(hCombo,CB_GETCURSEL,0,0L)==CB_ERR &&
  212.                      wcschr(g_szBuf, ' ')) {
  213.                   W2A (ErrMsgInvalidName, szAnsiString, 256);
  214.                   MessageBox(
  215.                         hDlg,
  216.                         szAnsiString,
  217.                         NULL,
  218.                         MB_ICONEXCLAMATION
  219.                   );
  220.                   break;
  221.                } else {
  222.                   nIndex = (int) SendMessage(hCombo,CB_FINDSTRINGEXACT,
  223.                      (WPARAM)0xffff,(LPARAM)(LPCSTR)g_szBuf);
  224.                   /* Line indices are 1 less than the number in
  225.                   **    the row heading
  226.                   */
  227.                   lrSel.m_nStartLine = GetDlgItemInt(hDlg, IDD_FROM,
  228.                         (BOOL FAR*)&fTranslated, FALSE) - 1;
  229.                   if(! fTranslated) {
  230.                      OutlineApp_ErrorMessage(g_lpApp,
  231.                            ErrMsgInvalidRange);
  232.                      break;
  233.                   }
  234.                   lrSel.m_nEndLine = GetDlgItemInt(hDlg, IDD_TO,
  235.                         (BOOL FAR*)&fTranslated, FALSE) - 1;
  236.                   if (!fTranslated ||
  237.                      (lrSel.m_nStartLine < 0) ||
  238.                      (lrSel.m_nEndLine < lrSel.m_nStartLine) ||
  239.                      (lrSel.m_nEndLine >= OutlineDoc_GetLineCount(
  240.                            lpOutlineDoc))) {
  241.                      OutlineApp_ErrorMessage(g_lpApp,
  242.                            ErrMsgInvalidRange);
  243.                      break;
  244.                   }
  245.                   if(nIndex != CB_ERR) {
  246.                      NameDlg_UpdateName(
  247.                            hCombo,
  248.                            lpOutlineDoc,
  249.                            nIndex,
  250.                            g_szBuf,
  251.                            &lrSel
  252.                      );
  253.                   } else {
  254.                      NameDlg_AddName(
  255.                            hCombo,
  256.                            lpOutlineDoc,
  257.                            g_szBuf,
  258.                            &lrSel
  259.                      );
  260.                   }
  261.                }
  262.                // fall through
  263.             case IDD_CLOSE:
  264.                /* Ignore data values entered into the controls */
  265.                /* and dismiss the dialog window returning FALSE */
  266.                EndDialog(hDlg,0);
  267.                break;
  268.             case IDD_DELETE:
  269.                GetDlgItemText(hDlg,IDD_COMBO,(LPSTR)szAnsiString,MAXNAMESIZE);
  270.                if((nIndex=(int)SendMessage(hCombo,CB_FINDSTRINGEXACT,
  271.                (WPARAM)0xffff,(LPARAM)(LPCSTR)szAnsiString))==CB_ERR) {
  272.                   W2A (ErrMsgNameNotFound, szAnsiString, 256);
  273.                   MessageBox(hDlg, szAnsiString, NULL, MB_ICONEXCLAMATION);
  274.                }
  275.                else {
  276.                   NameDlg_DeleteName(hCombo, lpOutlineDoc, nIndex);
  277.                }
  278.                break;
  279.             case IDD_COMBO:
  280.                if(HIWORD(lParam) == CBN_SELCHANGE) {
  281.                   nIndex=(int)SendMessage(hCombo, CB_GETCURSEL, 0, 0L);
  282.                   lpOutlineName = (LPOUTLINENAME)SendMessage(
  283.                         hCombo,
  284.                         CB_GETITEMDATA,
  285.                         (WPARAM)nIndex,
  286.                         0L
  287.                   );
  288.                   SetDlgItemInt(
  289.                         hDlg,
  290.                         IDD_FROM,
  291.                         (UINT) lpOutlineName->m_nStartLine + 1,
  292.                         FALSE
  293.                   );
  294.                   SetDlgItemInt(
  295.                         hDlg,
  296.                         IDD_TO,
  297.                         (UINT) lpOutlineName->m_nEndLine + 1,
  298.                         FALSE
  299.                   );
  300.                }
  301.          }
  302.          break;    /* End of WM_COMMAND */
  303.       default:
  304.          return FALSE;
  305.    }
  306.    return TRUE;
  307. } /* End of DefineNameDlgProc */
  308. /* GotoNameDlgProc
  309.  * ---------------
  310.  *
  311.  *      Dialog procedure for goto name
  312.  */
  313. BOOL CALLBACK EXPORT GotoNameDlgProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
  314. {
  315.    static HWND hLBName;
  316.    static LPOUTLINEDOC lpOutlineDoc = NULL;
  317.    static LPOUTLINENAMETABLE lpOutlineNameTable = NULL;
  318.    UINT nIndex;
  319.    LINERANGE lrLineRange;
  320.    LPOUTLINENAME lpOutlineName;
  321.    switch(Message) {
  322.       case WM_INITDIALOG:
  323.       /* initialize working variables */
  324.          lpOutlineDoc = (LPOUTLINEDOC) lParam;
  325.          lpOutlineNameTable = OutlineDoc_GetNameTable(lpOutlineDoc);
  326.          hLBName=GetDlgItem(hDlg,IDD_LINELISTBOX);
  327.          NameDlg_LoadListBox(lpOutlineNameTable, hLBName);
  328.          // highlight 1st item
  329.          SendMessage(hLBName, LB_SETCURSEL, 0, 0L);
  330.          // trigger to initialize edit control
  331.          SendMessage(hDlg, WM_COMMAND, (WPARAM)IDD_LINELISTBOX,
  332.             MAKELONG(hLBName, LBN_SELCHANGE));
  333.          break; /* End of WM_INITDIALOG */
  334.       case WM_CLOSE:
  335.       /* Closing the Dialog behaves the same as Cancel */
  336.          PostMessage(hDlg, WM_COMMAND, IDCANCEL, 0L);
  337.          break; /* End of WM_CLOSE */
  338.       case WM_COMMAND:
  339.          switch(wParam) {
  340.             case IDD_LINELISTBOX:
  341.                if(HIWORD(lParam) == LBN_SELCHANGE) {
  342.                   // update the line range display
  343.                   nIndex=(int)SendMessage(hLBName, LB_GETCURSEL, 0, 0L);
  344.                   lpOutlineName = (LPOUTLINENAME)SendMessage(hLBName, LB_GETITEMDATA,
  345.                                  (WPARAM)nIndex,0L);
  346.                   if (lpOutlineName) {
  347.                      SetDlgItemInt(
  348.                            hDlg,
  349.                            IDD_FROM,
  350.                            (UINT) lpOutlineName->m_nStartLine + 1,
  351.                            FALSE
  352.                      );
  353.                      SetDlgItemInt(
  354.                            hDlg,
  355.                            IDD_TO,
  356.                            (UINT) lpOutlineName->m_nEndLine + 1,
  357.                            FALSE
  358.                      );
  359.                   }
  360.                   break;
  361.                }
  362.                // double click will fall through
  363.                else if(HIWORD(lParam) != LBN_DBLCLK)
  364.                   break;
  365.             case IDOK:
  366.                nIndex=(int)SendMessage(hLBName,LB_GETCURSEL,0,0L);
  367.                if(nIndex!=LB_ERR) {
  368.                   lpOutlineName = (LPOUTLINENAME)SendMessage(hLBName,
  369.                         LB_GETITEMDATA, (WPARAM)nIndex, 0L);
  370.                   lrLineRange.m_nStartLine=lpOutlineName->m_nStartLine;
  371.                   lrLineRange.m_nEndLine = lpOutlineName->m_nEndLine;
  372.                   OutlineDoc_SetSel(lpOutlineDoc, &lrLineRange);
  373.                }   // fall through
  374.             case IDCANCEL:
  375.             /* Ignore data values entered into the controls */
  376.             /* and dismiss the dialog window returning FALSE */
  377.                EndDialog(hDlg,0);
  378.                break;
  379.          }
  380.          break;    /* End of WM_COMMAND */
  381.       default:
  382.          return FALSE;
  383.    }
  384.    return TRUE;
  385. } /* End of GotoNameDlgProc */
  386. /* NameDlg_LoadComboBox
  387.  * --------------------
  388.  *
  389.  *      Load defined names into combo box
  390.  */
  391. void NameDlg_LoadComboBox(LPOUTLINENAMETABLE lpOutlineNameTable,HWND hCombo)
  392. {
  393.    LPOUTLINENAME lpOutlineName;
  394.    int i, nIndex;
  395.    int nCount;
  396.    nCount=OutlineNameTable_GetCount((LPOUTLINENAMETABLE)lpOutlineNameTable);
  397.    if(!nCount) return;
  398.    SendMessage(hCombo,WM_SETREDRAW,(WPARAM)FALSE,0L);
  399.    for(i=0; i<nCount; i++) {
  400.       lpOutlineName=OutlineNameTable_GetName((LPOUTLINENAMETABLE)lpOutlineNameTable,i);
  401.       nIndex = (int)SendMessage(
  402.             hCombo,
  403.             CB_ADDSTRING,
  404.             0,
  405.             (LPARAM)(LPCSTR)lpOutlineName->m_szName
  406.       );
  407.       SendMessage(hCombo,CB_SETITEMDATA,(WPARAM)nIndex,(LPARAM)lpOutlineName);
  408.    }
  409.    SendMessage(hCombo,WM_SETREDRAW,(WPARAM)TRUE,0L);
  410. }
  411. /* NameDlg_LoadListBox
  412.  * -------------------
  413.  *
  414.  *      Load defined names into list box
  415.  */
  416. void NameDlg_LoadListBox(LPOUTLINENAMETABLE lpOutlineNameTable,HWND hListBox)
  417. {
  418.    int i;
  419.    int nCount;
  420.    int nIndex;
  421.    LPOUTLINENAME lpOutlineName;
  422.    nCount=OutlineNameTable_GetCount((LPOUTLINENAMETABLE)lpOutlineNameTable);
  423.    SendMessage(hListBox,WM_SETREDRAW,(WPARAM)FALSE,0L);
  424.    for(i=0; i<nCount; i++) {
  425.       lpOutlineName=OutlineNameTable_GetName((LPOUTLINENAMETABLE)lpOutlineNameTable,i);
  426.       nIndex = (int)SendMessage(
  427.             hListBox,
  428.             LB_ADDSTRING,
  429.             0,
  430.             (LPARAM)(LPCSTR)lpOutlineName->m_szName
  431.       );
  432.       SendMessage(hListBox,LB_SETITEMDATA,(WPARAM)nIndex,(LPARAM)lpOutlineName);
  433.    }
  434.    SendMessage(hListBox,WM_SETREDRAW,(WPARAM)TRUE,0L);
  435. }
  436. /* NameDlg_AddName
  437.  * ---------------
  438.  *
  439.  *      Add a name to the name table corresponding to the name dialog
  440.  *      combo box.
  441.  */
  442. void NameDlg_AddName(HWND hCombo, LPOUTLINEDOC lpOutlineDoc, LPOLESTR lpszName, LPLINERANGE lplrSel)
  443. {
  444.    LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp;
  445.    LPOUTLINENAME lpOutlineName;
  446.    lpOutlineName = OutlineApp_CreateName(lpOutlineApp);
  447.    if (lpOutlineName) {
  448.       OLESTRCPY(lpOutlineName->m_szName, lpszName);
  449.       lpOutlineName->m_nStartLine = lplrSel->m_nStartLine;
  450.       lpOutlineName->m_nEndLine = lplrSel->m_nEndLine;
  451.       OutlineDoc_AddName(lpOutlineDoc, lpOutlineName);
  452.    } else {
  453.       // REVIEW: do we need error message here?
  454.    }
  455. }
  456. /* NameDlg_UpdateName
  457.  * ------------------
  458.  *
  459.  *      Update a name in the name table corresponding to a name in
  460.  *      the name dialog combo box.
  461.  */
  462. void NameDlg_UpdateName(HWND hCombo, LPOUTLINEDOC lpOutlineDoc, int nIndex, LPOLESTR lpszName, LPLINERANGE lplrSel)
  463. {
  464.    LPOUTLINENAME lpOutlineName;
  465.    lpOutlineName = (LPOUTLINENAME)SendMessage(
  466.          hCombo,
  467.          CB_GETITEMDATA,
  468.          (WPARAM)nIndex,
  469.          0L
  470.    );
  471.    OutlineName_SetName(lpOutlineName, lpszName);
  472.    OutlineName_SetSel(lpOutlineName, lplrSel, TRUE /* name modified */);
  473.    OutlineDoc_SetModified(lpOutlineDoc, TRUE, FALSE, FALSE);
  474. }
  475. /* NameDlg_DeleteName
  476.  * ------------------
  477.  *
  478.  *      Delete a name from the name dialog combo box and corresponding
  479.  *      name table.
  480.  */
  481. void NameDlg_DeleteName(HWND hCombo, LPOUTLINEDOC lpOutlineDoc, UINT nIndex)
  482. {
  483.    SendMessage(hCombo,CB_DELETESTRING,(WPARAM)nIndex,0L);
  484.    OutlineDoc_DeleteName(lpOutlineDoc, nIndex);
  485. }
  486. /* PlaceBitmap
  487.  * -----------
  488.  *
  489.  *      Places a bitmap centered in the specified control in the dialog on the
  490.  *      specified DC.
  491.  *
  492.  */
  493. PlaceBitmap(HWND hDlg, int control, HDC hDC, HBITMAP hBitmap)
  494. {
  495.    BITMAP bm;
  496.    HDC hdcmem;
  497.    HBITMAP hbmOld;
  498.    RECT rcControl;     // Rect of dialog control
  499.    int width, height;
  500.    GetObject(hBitmap, sizeof(BITMAP), &bm);
  501.    hdcmem= CreateCompatibleDC(hDC);
  502.    hbmOld = SelectObject(hdcmem, hBitmap);
  503.    // Get rect of control in screen coords, and translate to our dialog
  504.    // box's coordinates
  505.    GetWindowRect(GetDlgItem(hDlg, control), &rcControl);
  506.    MapWindowPoints(NULL, hDlg, (LPPOINT)&rcControl, 2);
  507.    width  = rcControl.right - rcControl.left;
  508.    height = rcControl.bottom - rcControl.top;
  509.    BitBlt(hDC, rcControl.left + (width - bm.bmWidth) / 2,
  510.             rcControl.top + (height - bm.bmHeight) /2,
  511.             bm.bmWidth, bm.bmHeight,
  512.             hdcmem, 0, 0, SRCCOPY);
  513.    SelectObject(hdcmem, hbmOld);
  514.    DeleteDC(hdcmem);
  515.    return 1;
  516. }
  517. /* AboutDlgProc
  518.  * ------------
  519.  *
  520.  *      Dialog procedure for the About function
  521.  */
  522. BOOL CALLBACK EXPORT AboutDlgProc(HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam)
  523. {
  524.    int  narrVersion[2];
  525.    static HBITMAP hbmLogo;
  526.    char   szAnsiString[256];
  527.    char   szAppName[250];
  528.    switch(Message) {
  529.       case WM_INITDIALOG:
  530.          // get version number of app
  531.          W2A (APPNAME, szAppName, 250);
  532.          wsprintf(szAnsiString, "About %s", (LPSTR)szAppName);
  533.          SetWindowText(hDlg, (LPCSTR)szAnsiString);
  534.          OutlineApp_GetAppVersionNo(g_lpApp, narrVersion);
  535.          wsprintf(szAnsiString, "%s version %d.%d", (LPSTR) APPDESC,
  536.             narrVersion[0], narrVersion[1]);
  537.          SetDlgItemText(hDlg, IDD_APPTEXT, (LPCSTR)szAnsiString);
  538.          // Load bitmap for displaying later
  539.          hbmLogo = LoadBitmap(g_lpApp->m_hInst, "LogoBitmap");
  540.          TraceDebug(hDlg, IDD_BITMAPLOCATION);
  541.          ShowWindow(GetDlgItem(hDlg, IDD_BITMAPLOCATION), SW_HIDE);
  542.          break;
  543.       case WM_PAINT:
  544.          {
  545.          PAINTSTRUCT ps;
  546.          BeginPaint(hDlg, &ps);
  547.          // Display bitmap in IDD_BITMAPLOCATION control area
  548.          PlaceBitmap(hDlg, IDD_BITMAPLOCATION, ps.hdc, hbmLogo);
  549.          EndPaint(hDlg, &ps);
  550.          }
  551.          break;
  552.       case WM_CLOSE :
  553.          PostMessage(hDlg, WM_COMMAND, IDOK, 0L);
  554.          break;
  555.       case WM_COMMAND :
  556.          switch(wParam) {
  557.             case IDOK:
  558.             case IDCANCEL:
  559.                if (hbmLogo) DeleteObject(hbmLogo);
  560.                EndDialog(hDlg,0);
  561.                break;
  562.          }
  563.          break;
  564.       default :
  565.          return FALSE;
  566.    }
  567.    return TRUE;
  568. }