home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap02 / query / query.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  8.3 KB  |  338 lines

  1. /*
  2.  * QUERY.CPP
  3.  * Demonstration of QueryInterface and different techniques to
  4.  * implement multiple interfaces.
  5.  *
  6.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  7.  *
  8.  * Kraig Brockschmidt, Microsoft
  9.  * Internet  :  kraigb@microsoft.com
  10.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  11.  */
  12.  
  13.  
  14. #define INITGUIDS
  15. #include <windows.h>
  16. #include "query.h"
  17.  
  18.  
  19. /*
  20.  * WinMain
  21.  *
  22.  * Purpose:
  23.  *  Main entry point of application.
  24.  */
  25.  
  26. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hInstPrev
  27.     , LPSTR pszCmdLine, int nCmdShow)
  28.     {
  29.     MSG     msg;
  30.     PAPP    pApp;
  31.  
  32.     pApp=new CApp(hInst, hInstPrev, nCmdShow);
  33.  
  34.     if (NULL==pApp)
  35.         return -1;
  36.  
  37.     if (pApp->Init())
  38.         {
  39.         while (GetMessage(&msg, NULL, 0,0 ))
  40.             {
  41.             TranslateMessage(&msg);
  42.             DispatchMessage(&msg);
  43.             }
  44.         }
  45.  
  46.     delete pApp;
  47.     return msg.wParam;
  48.     }
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56. /*
  57.  * QueryWndProc
  58.  *
  59.  * Purpose:
  60.  *  Standard window class procedure.
  61.  */
  62.  
  63. LRESULT APIENTRY QueryWndProc(HWND hWnd, UINT iMsg, WPARAM wParam
  64.     , LPARAM lParam)
  65.     {
  66.     PAPP        pApp;
  67.     HRESULT     hr;
  68.     BOOL        fRes;
  69.     ISampleOne *pISampleOne;
  70.     ISampleTwo *pISampleTwo;
  71.     const UINT  CCHTEMP=80;
  72.     TCHAR       szTemp[CCHTEMP];
  73.  
  74.     COMMANDPARAMS(wID, wCode, hWndMsg);
  75.  
  76.     pApp=(PAPP)GetWindowLong(hWnd, QUERYWL_STRUCTURE);
  77.  
  78.     switch (iMsg)
  79.         {
  80.         case WM_NCCREATE:
  81.             pApp=(PAPP)(((LPCREATESTRUCT)lParam)->lpCreateParams);
  82.             SetWindowLong(hWnd, QUERYWL_STRUCTURE, (LONG)pApp);
  83.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  84.  
  85.  
  86.         case WM_DESTROY:
  87.             PostQuitMessage(0);
  88.             break;
  89.  
  90.  
  91.         case WM_COMMAND:
  92.             switch (wID)
  93.                 {
  94.                 case IDM_OBJECTCREATE1:
  95.                     if (NULL!=pApp->m_pIUnknown)
  96.                         pApp->m_pIUnknown->Release();
  97.  
  98.                     fRes=CreateObject1(&pApp->m_pIUnknown);
  99.  
  100.                     pApp->Message(fRes ? TEXT("Object 1 created")
  101.                         : TEXT("Object 1 creation failed"));
  102.  
  103.                     break;
  104.  
  105.  
  106.                 case IDM_OBJECTCREATE2:
  107.                     if (NULL!=pApp->m_pIUnknown)
  108.                         pApp->m_pIUnknown->Release();
  109.  
  110.                     fRes=CreateObject2(&pApp->m_pIUnknown);
  111.  
  112.                     pApp->Message(fRes ? TEXT("Object 2 created")
  113.                         : TEXT("Object 2 creation failed"));
  114.  
  115.                     break;
  116.  
  117.  
  118.                 case IDM_OBJECTCREATE3:
  119.                     if (NULL!=pApp->m_pIUnknown)
  120.                         pApp->m_pIUnknown->Release();
  121.  
  122.                     fRes=CreateObject3(&pApp->m_pIUnknown);
  123.  
  124.                     pApp->Message(fRes ? TEXT("Object 3 created")
  125.                         : TEXT("Object 3 creation failed"));
  126.  
  127.                     break;
  128.  
  129.  
  130.                 case IDM_OBJECTRELEASE:
  131.                     if (NULL==pApp->m_pIUnknown)
  132.                         {
  133.                         pApp->Message(TEXT("There is no object"));
  134.                         break;
  135.                         }
  136.  
  137.                     if (0==pApp->m_pIUnknown->Release())
  138.                         {
  139.                         pApp->m_pIUnknown=NULL;
  140.                         pApp->Message(TEXT("Object released"));
  141.                         }
  142.  
  143.                     break;
  144.  
  145.  
  146.                 case IDM_OBJECTGETMESSAGE:
  147.                     if (NULL==pApp->m_pIUnknown)
  148.                         {
  149.                         pApp->Message(TEXT("There is no object"));
  150.                         break;
  151.                         }
  152.  
  153.                     hr=pApp->m_pIUnknown->QueryInterface
  154.                         (IID_ISampleOne, (PPVOID)&pISampleOne);
  155.  
  156.                     if (FAILED(hr))
  157.                         {
  158.                         pApp->Message(TEXT("Failed to get ISampleOne"));
  159.                         break;
  160.                         }
  161.  
  162.                     hr=pISampleOne->GetMessage(szTemp, CCHTEMP);
  163.  
  164.                     pApp->Message(SUCCEEDED(hr) ? szTemp
  165.                         : TEXT("ISampleOne::GetMessage failed"));
  166.  
  167.                     //m_pIUnknown is still valid after this Release
  168.                     pISampleOne->Release();
  169.                     break;
  170.  
  171.  
  172.                 case IDM_OBJECTGETSTRING:
  173.                     if (NULL==pApp->m_pIUnknown)
  174.                         {
  175.                         pApp->Message(TEXT("There is no object"));
  176.                         break;
  177.                         }
  178.  
  179.                     hr=pApp->m_pIUnknown->QueryInterface
  180.                         (IID_ISampleTwo, (PPVOID)&pISampleTwo);
  181.  
  182.                     if (FAILED(hr))
  183.                         {
  184.                         pApp->Message(TEXT("Failed to get ISampleTwo"));
  185.                         break;
  186.                         }
  187.  
  188.                     hr=pISampleTwo->GetString(szTemp, CCHTEMP);
  189.  
  190.                     pApp->Message(SUCCEEDED(hr) ? szTemp
  191.                         : TEXT("ISampleTwp::GetString failed"));
  192.  
  193.                     //m_pIUnknown is still valid after this Release
  194.                     pISampleTwo->Release();
  195.                     break;
  196.  
  197.  
  198.                 case IDM_OBJECTEXIT:
  199.                     PostMessage(hWnd, WM_CLOSE, 0, 0L);
  200.                     break;
  201.                 }
  202.             break;
  203.  
  204.         default:
  205.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  206.         }
  207.  
  208.     return 0L;
  209.     }
  210.  
  211.  
  212.  
  213.  
  214. /*
  215.  * CApp::CApp
  216.  * CApp::~CApp
  217.  *
  218.  * Constructor Parameters:
  219.  *  hInst           HINSTANCE of the Application from WinMain
  220.  *  hInstPrev       HINSTANCE of a previous instance from WinMain
  221.  *  nCmdShow        UINT specifying how to show the app window,
  222.  *                  from WinMain.
  223.  */
  224.  
  225. CApp::CApp(HINSTANCE hInst, HINSTANCE hInstPrev
  226.     , UINT nCmdShow)
  227.     {
  228.     //Initialize WinMain parameter holders.
  229.     m_hInst     =hInst;
  230.     m_hInstPrev =hInstPrev;
  231.     m_nCmdShow  =nCmdShow;
  232.  
  233.     m_hWnd=NULL;
  234.     m_pIUnknown=NULL;
  235.  
  236.     return;
  237.     }
  238.  
  239.  
  240. CApp::~CApp(void)
  241.     {
  242.     //Release the object if we still have it.
  243.     ReleaseInterface(m_pIUnknown);
  244.     return;
  245.     }
  246.  
  247.  
  248.  
  249.  
  250. /*
  251.  * CApp::Init
  252.  *
  253.  * Purpose:
  254.  *  Initializes an CApp object by registering window classes,
  255.  *  creating the main window, and doing anything else prone to
  256.  *  failure.  If this function fails the caller should guarantee
  257.  *  that the destructor is called.
  258.  *
  259.  * Parameters:
  260.  *  None
  261.  *
  262.  * Return Value:
  263.  *  BOOL            TRUE if successful, FALSE otherwise.
  264.  */
  265.  
  266. BOOL CApp::Init(void)
  267.     {
  268.     WNDCLASS    wc;
  269.  
  270.     if (!m_hInstPrev)
  271.         {
  272.         wc.style          = CS_HREDRAW | CS_VREDRAW;
  273.         wc.lpfnWndProc    = QueryWndProc;
  274.         wc.cbClsExtra     = 0;
  275.         wc.cbWndExtra     = CBWNDEXTRA;
  276.         wc.hInstance      = m_hInst;
  277.         wc.hIcon          = LoadIcon(m_hInst, TEXT("Icon"));
  278.         wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
  279.         wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  280.         wc.lpszMenuName   = MAKEINTRESOURCE(IDR_MENU);
  281.         wc.lpszClassName  = TEXT("QUERY");
  282.  
  283.         if (!RegisterClass(&wc))
  284.             return FALSE;
  285.         }
  286.  
  287.     m_hWnd=CreateWindow(TEXT("QUERY"), TEXT("QueryInterface Demo")
  288.         , WS_MINIMIZEBOX | WS_OVERLAPPEDWINDOW
  289.         ,35, 35, 350, 250, NULL, NULL, m_hInst, this);
  290.  
  291.     if (NULL==m_hWnd)
  292.         return FALSE;
  293.  
  294.     ShowWindow(m_hWnd, m_nCmdShow);
  295.     UpdateWindow(m_hWnd);
  296.  
  297.     return TRUE;
  298.     }
  299.  
  300.  
  301.  
  302.  
  303. /*
  304.  * CApp::Message
  305.  *
  306.  * Purpose:
  307.  *  Displays a message in the client area of the window.  This is
  308.  *  just to centralize the call to simpify other code.
  309.  *
  310.  * Parameters:
  311.  *  psz             LPTSTR to the string to display.
  312.  *
  313.  * Return Value:
  314.  *  None
  315.  */
  316.  
  317. void inline CApp::Message(LPTSTR psz)
  318.     {
  319.     HDC     hDC;
  320.     RECT    rc;
  321.  
  322.     hDC=GetDC(m_hWnd);
  323.     GetClientRect(m_hWnd, &rc);
  324.  
  325.     SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
  326.     SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  327.  
  328.     /*
  329.      * We'll just be sloppy and clear the whole window as
  330.      * well as write the string with one ExtTextOut call.
  331.      * No word wrapping here...
  332.      */
  333.  
  334.     ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, psz, lstrlen(psz), NULL);
  335.     ReleaseDC(m_hWnd, hDC);
  336.     return;
  337.     }
  338.