[原创]VC6和eVC4的SDK编程框架对比

羽灵   2009-8-24 10:22 楼主
在VC6的 IDE 中利用 Visual Assistant 的 Win32 Standard application 模板,写一个类名,例如“myclass”,就可以编译通过并正常运行了:

  1. #include
  2. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  3. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
  4. {
  5.     static TCHAR szAppName[] = TEXT ("myclass");
  6.     HWND         hwnd;
  7.     MSG          msg;
  8.     WNDCLASSEX   wndclassex = {0};
  9.     wndclassex.cbSize        = sizeof(WNDCLASSEX);
  10.     wndclassex.style         = CS_HREDRAW | CS_VREDRAW;
  11.     wndclassex.lpfnWndProc   = WndProc;
  12.     wndclassex.cbClsExtra    = 0;
  13.     wndclassex.cbWndExtra    = 0;
  14.     wndclassex.hInstance     = hInstance;
  15.     wndclassex.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
  16.     wndclassex.hCursor       = LoadCursor (NULL, IDC_ARROW);
  17.     wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
  18.     wndclassex.lpszMenuName  = NULL;
  19.     wndclassex.lpszClassName = szAppName;
  20.     wndclassex.hIconSm       = wndclassex.hIcon;
  21.        
  22.     if (!RegisterClassEx (&wndclassex))
  23.     {
  24.         MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR);
  25.         return 0;
  26.     }
  27.     hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW,
  28.                                   szAppName,
  29.                                   TEXT ("WindowTitle"),
  30.                                   WS_OVERLAPPEDWINDOW,
  31.                                   CW_USEDEFAULT,
  32.                                   CW_USEDEFAULT,
  33.                                   CW_USEDEFAULT,
  34.                                   CW_USEDEFAULT,
  35.                                   NULL,
  36.                                   NULL,
  37.                                   hInstance,
  38.                                   NULL);
  39.                                                   
  40.     ShowWindow (hwnd, iCmdShow);
  41.     UpdateWindow (hwnd);
  42.        
  43.     while (GetMessage (&msg, NULL, 0, 0))
  44.     {
  45.         TranslateMessage (&msg);
  46.         DispatchMessage (&msg);
  47.     }
  48.     return msg.wParam;
  49. }
  50. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  51. {
  52.     HDC hdc;
  53.     PAINTSTRUCT ps;
  54.     switch (message)
  55.     {
  56.     case WM_CREATE:
  57.         return (0);
  58.                
  59.     case WM_PAINT:
  60.         hdc = BeginPaint (hwnd, &ps);
  61.         TextOut (hdc, 0, 0, "A Window!", 27);
  62.         EndPaint (hwnd, &ps);
  63.         return (0);
  64.                
  65.     case WM_DESTROY:
  66.         PostQuitMessage (0);
  67.         return (0);
  68.     }
  69.     return DefWindowProc (hwnd, message, wParam, lParam);
  70. }


可是到了eVC4,这个框架就会出现许多编译错误,修改如下才能编译通过:

  1. #include
  2. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

  3. int WINAPI WinMain (HINSTANCE hInstance,
  4.                     HINSTANCE hPrevInstance,
  5.                     LPWSTR lpCmdLine,
  6.                     int iCmdShow)
  7. {
  8.     static TCHAR szAppName[] = TEXT ("myclass");
  9.     HWND         hwnd;
  10.     MSG          msg;
  11.     WNDCLASS   wndclassex = {0};
  12. //    wndclassex.cbSize        = sizeof(WNDCLASSEX);
  13.     wndclassex.style         = CS_HREDRAW | CS_VREDRAW;
  14.     wndclassex.lpfnWndProc   = WndProc;
  15.     wndclassex.cbClsExtra    = 0;
  16.     wndclassex.cbWndExtra    = 0;
  17.     wndclassex.hInstance     = hInstance;
  18.     wndclassex.hIcon         = NULL;// LoadIcon (NULL, IDI_APPLICATION);
  19.     wndclassex.hCursor       = LoadCursor (NULL, IDC_ARROW);
  20.     wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
  21.     wndclassex.lpszMenuName  = NULL;
  22.     wndclassex.lpszClassName = szAppName;
  23. //    wndclassex.hIconSm       = wndclassex.hIcon;
  24.        
  25.     if (!RegisterClass(&wndclassex))
  26.     {
  27.         MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR);
  28.         return 0;
  29.     }
  30.     hwnd = CreateWindow(
  31.                                   szAppName,
  32.                                   TEXT ("WindowTitle"),
  33.                                   WS_VISIBLE,
  34.                                   CW_USEDEFAULT,
  35.                                   CW_USEDEFAULT,
  36.                                   CW_USEDEFAULT,
  37.                                   CW_USEDEFAULT,
  38.                                   NULL,
  39.                                   NULL,
  40.                                   hInstance,
  41.                                   NULL);
  42.                                                   
  43.     ShowWindow (hwnd, iCmdShow);
  44.     UpdateWindow (hwnd);
  45.        
  46.     while (GetMessage (&msg, NULL, 0, 0))
  47.     {
  48.         TranslateMessage (&msg);
  49.         DispatchMessage (&msg);
  50.     }
  51.     return msg.wParam;
  52. }
  53. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  54. {
  55.     HDC hdc;
  56.     PAINTSTRUCT ps;
  57.     switch (message)
  58.     {
  59.     case WM_CREATE:
  60.         return (0);
  61.                
  62.     case WM_PAINT:
  63.         hdc = BeginPaint (hwnd, &ps);
  64. //        TextOut (hdc, 0, 0, "A Window!", 27);
  65.         RECT rect;
  66.         GetClientRect (hwnd, &rect);   
  67.         DrawText (hdc, TEXT ("Hello Windows CE!"), -1, &rect,               
  68.             DT_CENTER | DT_VCENTER | DT_SINGLELINE);   
  69.         EndPaint (hwnd, &ps);
  70.         return (0);
  71.                
  72.     case WM_DESTROY:
  73.         PostQuitMessage (0);
  74.         return (0);
  75.     }
  76.     return DefWindowProc (hwnd, message, wParam, lParam);
  77. }


其实主要是这两点不同,1. eVC下的字符只能用双字节的;2. eVC不支持Ex后缀系列API。

回复评论 (4)

当然,上面的eVC的程序没有创建关闭按钮,不像VC那样默认就有,所以还不是一个完美的模板。下面这个程序不仅创建了关闭按钮,而且还比较巧妙的封装了消息,事实上我猜想MFC就是这样封装SDK的:

  1. //======================================================================
  2. // HelloCE - A simple application for Windows CE
  3. //
  4. // Written for the book Programming Windows CE
  5. // Copyright (C) 2001 Douglas Boling
  6. //
  7. //======================================================================

  8. #include                  
  9. // For all that Windows stuff
  10. #include                
  11. // Command bar includes
  12. #include "helloce.h"                 

  13. // Program-specific stuff
  14. //----------------------------------------------------------------------
  15. // Global data
  16. //
  17. const TCHAR szAppName[] = TEXT("HelloCE");
  18. HINSTANCE hInst;                     // Program instance handle

  19. // Message dispatch table for MainWindowProc
  20. const struct decodeUINT MainMessages[] =
  21. {   
  22.         WM_CREATE, DoCreateMain,   
  23.         WM_PAINT, DoPaintMain,   
  24.         WM_HIBERNATE, DoHibernateMain,   
  25.         WM_ACTIVATE, DoActivateMain,   
  26.         WM_DESTROY, DoDestroyMain,
  27. };

  28. //======================================================================
  29. // Program entry point
  30. //

  31. int WINAPI WinMain (HINSTANCE hInstance,
  32.                                         HINSTANCE hPrevInstance,                    
  33.                                         LPWSTR lpCmdLine,
  34.                                         int nCmdShow)
  35. {   
  36.         MSG msg;   
  37.         int rc = 0;   
  38.         HWND hwndMain;     
  39.         // Initialize application.   
  40.         rc = InitApp (hInstance);   
  41.         if (rc) return rc;     
  42.        
  43.         // Initialize this instance.   
  44.         hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow);   
  45.         if (hwndMain == 0) return 0x10;     
  46.         // Application message loop   
  47.         while (GetMessage (&msg, NULL, 0, 0))
  48.         {        
  49.                 TranslateMessage (&msg);        
  50.                 DispatchMessage (&msg);   
  51.         }     
  52.         // Instance cleanup   
  53.         return TermInstance (hInstance, msg.wParam);
  54. }

  55. //---------------------------------------------------------------
  56. // InitApp - Application initialization
  57. //
  58. int InitApp (HINSTANCE hInstance)
  59. {   
  60.         WNDCLASS wc;

  61.         #if defined(WIN32_PLATFORM_PSPC)           
  62.                 // If Pocket PC, allow only one instance of the application.   
  63.                 HWND hWnd = FindWindow (szAppName, NULL);   
  64.                 if (hWnd)
  65.                 {        
  66.                         SetForegroundWindow ((HWND)(((DWORD)hWnd) | 0x01));            
  67.                         return -1;   
  68.                 }
  69.         #endif        
  70.                
  71.                 // Register application main window class.   
  72.                 wc.style = 0;                             // Window style   
  73.                 wc.lpfnWndProc = MainWndProc;             // Callback function   
  74.                 wc.cbClsExtra = 0;                        // Extra class data   
  75.                 wc.cbWndExtra = 0;                        // Extra window data   
  76.                 wc.hInstance = hInstance;                 // Owner handle   
  77.                 wc.hIcon = NULL;                          // Application icon   
  78.                 wc.hCursor = LoadCursor (NULL, IDC_ARROW); // Default cursor   
  79.                 wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);   
  80.                 wc.lpszMenuName =  NULL;                  // Menu name   
  81.                 wc.lpszClassName = szAppName;             // Window class name     
  82.                 if (RegisterClass (&wc) == 0)
  83.                         return 1;   
  84.                 return 0;
  85. }

  86. //------------------------------------------------------------------
  87. // InitInstance - Instance initialization
  88. //
  89. HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine, int nCmdShow)
  90. {   
  91.         HWND hWnd;     
  92.        
  93.         // Save program instance handle in global variable.   
  94.         hInst = hInstance;     
  95.        
  96.         // Create main window.
  97.     hWnd = CreateWindow (szAppName,           // Window class                        
  98.                 TEXT("Hello"),       // Window title                        
  99.                 WS_VISIBLE,          // Style flags                        
  100.                 CW_USEDEFAULT,       // x position                        
  101.                 CW_USEDEFAULT,       // y position                        
  102.                 CW_USEDEFAULT,       // Initial width                        
  103.                 CW_USEDEFAULT,       // Initial height                        
  104.                 NULL,                // Parent                        
  105.                 NULL,                // Menu, must be null                        
  106.                 hInstance,           // Application instance                        
  107.                 NULL);               // Pointer to create                                             
  108.                                                          // parameters   
  109.         if (!IsWindow (hWnd)) return 0; // Fail if not created.     
  110.        
  111.         // Standard show and update calls   
  112.         ShowWindow (hWnd, nCmdShow);   
  113.         UpdateWindow (hWnd);   
  114.         return hWnd;
  115. }

  116. //----------------------------------------------------------------------
  117. // TermInstance - Program cleanup
  118. //
  119. int TermInstance (HINSTANCE hInstance, int nDefRC)
  120. {   
  121.         return nDefRC;
  122. }

  123. //======================================================================
  124. // Message handling procedures for main window
  125. //
  126. //----------------------------------------------------------------------
  127. // MainWndProc - Callback function for application window
  128. //
  129. LRESULT CALLBACK MainWndProc (HWND hWnd,
  130.                                                           UINT wMsg,
  131.                                                           WPARAM wParam,
  132.                                                           LPARAM lParam)
  133. {   
  134.         INT i;   
  135.         //   
  136.         // Search message list to see if we need to handle this   
  137.         // message.  If in list, call procedure.   
  138.         //   
  139.         for (i = 0; i < dim(MainMessages); i++)
  140.         {        
  141.                 if (wMsg == MainMessages[i].Code)            
  142.                         return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);   
  143.         }   
  144.         return DefWindowProc (hWnd, wMsg, wParam, lParam);
  145. }
  146. //----------------------------------------------------------------------
  147. // DoCreateMain - Process WM_CREATE message for window.
  148. //
  149. LRESULT DoCreateMain (HWND hWnd, UINT wMsg, WPARAM wParam,                       
  150.                                           LPARAM lParam)
  151. {   
  152.         HWND hwndCB;   
  153.        
  154.         // Create a command bar.   
  155.         hwndCB = CommandBar_Create (hInst, hWnd, IDC_CMDBAR);  
  156.        
  157.         // Add exit button to command bar.     
  158.         CommandBar_AddAdornments (hwndCB, 0, 0);   

  159.     return 0;
  160. }
  161. //----------------------------------------------------------------------
  162. // DoPaintMain - Process WM_PAINT message for window.
  163. //
  164. LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam,                     
  165.                                          LPARAM lParam)
  166. {   
  167.         PAINTSTRUCT ps;   
  168.         RECT rect;   
  169.         HDC hdc;   
  170.        
  171.         // Adjust the size of the client rectangle to take into account   
  172.         // the command bar height.   
  173.         GetClientRect (hWnd, &rect);   
  174.         rect.top += CommandBar_Height (GetDlgItem (hWnd, IDC_CMDBAR));     
  175.         hdc = BeginPaint (hWnd, &ps);     
  176.         DrawText (hdc, TEXT ("Hello Windows CE!"), -1, &rect,               
  177.                           DT_CENTER | DT_VCENTER | DT_SINGLELINE);   
  178.         EndPaint (hWnd, &ps);     
  179.         return 0;
  180. }

  181. //----------------------------------------------------------------------
  182. // DoHibernateMain - Process WM_HIBERNATE message for window.
  183. //
  184. LRESULT DoHibernateMain (HWND hWnd, UINT wMsg, WPARAM wParam,                          
  185.                                                  LPARAM lParam)
  186. {     
  187.         // If not the active window, nuke the command bar to save memory.   
  188.         if (GetActiveWindow() != hWnd)        
  189.                 CommandBar_Destroy (GetDlgItem (hWnd, IDC_CMDBAR));    return 0;
  190. }

  191. //----------------------------------------------------------------------
  192. // DoActivateMain - Process WM_ACTIVATE message for window.
  193. //
  194. LRESULT DoActivateMain (HWND hWnd, UINT wMsg, WPARAM wParam,                        
  195.                                                 LPARAM lParam)
  196. {   
  197.         HWND hwndCB;
  198.         // If activating and no command bar, create it.   
  199.         if ((LOWORD (wParam) != WA_INACTIVE) &&        (GetDlgItem (hWnd, IDC_CMDBAR) == 0))
  200.         {        
  201.                 // Create a command bar.        
  202.                 hwndCB = CommandBar_Create (hInst, hWnd, IDC_CMDBAR);         
  203.                 // Add exit button to command bar.        
  204.                 CommandBar_AddAdornments (hwndCB, 0, 0);   
  205.         }   
  206.         return 0;
  207. }

  208. //----------------------------------------------------------------------
  209. // DoDestroyMain - Process WM_DESTROY message for window.
  210. //
  211. LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam,                        
  212.                                            LPARAM lParam)
  213. {   
  214.         PostQuitMessage (0);   
  215.         return 0;
  216. }
点赞  2009-8-24 10:28
eVC不支持Ex后缀系列API?

这个总结是错误的。如CoInitializeEx,只支持Ex的,CoInitialize是不被支持的。
点赞  2009-8-24 12:41
学习
点赞  2009-8-24 13:44
引用: 引用 2 楼 91program 的回复:
eVC不支持Ex后缀系列API?

这个总结是错误的。如CoInitializeEx,只支持Ex的,CoInitialize是不被支持的。


有见地!你举的反例非常正确。想我当年把 VC6 的 SAPI TTS 移植到 eVC 时其中的一个修改就是用 Ex 代替没 Ex 的 CoInitialize。

说是“当年”,其实是一个月前
点赞  2009-8-24 14:30
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复