首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

ATL GUI 程式設計(一):從 Hello World 起步,探秘 ATL 核心模組

     編輯:關於VC++

第一章:免不了的「Hello, World!」

如同所有入門教程,我也以「Hello, World!」起步,再逐步深入剖析 ATL 版本的必要資訊,並介紹 Win32 中鮮為人知的細節:WinMain 的 _t 相容性、如何在 MessageBox 加入自訂圖示等。

Hello World 程式的共性特徵

  • 幾乎所有初學者都能獨立撰寫、編譯、執行。
  • 體現語言環境典型配置方式。
  • 包含語言特定的程式入口點。
  • 含有典型輸出語句(通常最簡單、常用)。
  • 清晰展示程式執行典型流程。
  • 可能表現語言其他特點。

C 語言版

#include <stdio.h>
int main() { printf( "Hello, World!\n" ); return 0; }

對應特徵:main 為入口、printf 輸出、函數為基本單位、需 include 頭文件、\n 為跳脫字元。

Win32 SDK 版

#include <windows.h>
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{ MessageBox( NULL, TEXT("Hello, World!"), TEXT("Hello"), 0 ); return 0; }

揭示:需 windows.h、入口為 WinMain、MessageBox 為常用輸出、WINAPI 即 __stdcall、HINSTANCE/LPSTR 為 Win32 型別、TEXT 宏保證 ANSI/Unicode 相容。

改良版:加入 tchar.h

#include <windows.h>
#include <tchar.h>
int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd )
{ MessageBox( NULL, _T("Hello, World!"), _T("Hello"), 0 ); return 0; }

差異:tchar.h 提供 CRT 層級 ANSI/Unicode 相容、_tWinMain 相容命令列參數、_T 宏比 TEXT 更簡短。

ATL 版 Hello World

請建立 Win32 Application 專案(非 ATL/COM Wizard):

//////////////////////////////////////////////////////////////////////////
// ATL GUI 程式設計配套原始碼
// 第一章 不能免俗的 "Hello, World!"
// 專案名稱:HelloWorld
// 作者:李馬
// https://www.titilima.cn
//////////////////////////////////////////////////////////////////////////
#include <atlbase.h>
CComModule _Module;
int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd )
{
    _Module.Init( NULL, hInstance );
    MessageBox( NULL, _T("Hello, World!"), _T("Hello"), 0 );
    _Module.Term();
    return 0;
}

代碼解讀

  • atlbase.h:ATL 核心頭文件,相當於 SDK 的 windows.h。
  • CComModule _Module:模組類實例,貫穿 ATL 框架。
  • _Module.Init/Tem:模組初始化與卸載。

「不過如此」——你的猜想

  1. atlbase.h 為 ATL 必含頭文件。
  2. CComModule 為模組類,_Module 為實例。
  3. WinMain 未變。
  4. Init 初始化模組,Term 結束處理。
  5. 最後以 return 結尾。

完全正確!

大抵如此:關鍵補充

atlbase.h 的核心內容

  • Win32 必備頭文件(windows.h、tchar.h 等)。
  • CComModule 定義:GUI 視角可視為 HINSTANCE 封裝。
  • 簡單工具類:ATL 3.0 (VC6) 主供 COM 智慧指標 (CComPtr、CComBSTR);ATL 7.0 (VS2003) 另含 CRegKey、CHandle 等。

CComModule 核心成員(GUI 視角)

HRESULT Init( _ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL );
void Term();
HINSTANCE GetModuleInstance(); // 取得 m_hInst
HINSTANCE GetResourceInstance(); // 取得 m_hInstResource,預設等於 m_hInst

全域變數 _Module 貫穿 ATL 框架。需用模組實例句柄時(如 LoadIcon),調用:

extern CComModule _Module;
HICON hIcon = ::LoadIcon( _Module.GetResourceInstance(), MAKEINTRESOURCE( IDI_YOURICON ) );

擴展範例:使用外部資源 (shell32.dll)

#include <atlbase.h>
CComModule _Module;
int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd )
{
    _Module.Init( NULL, hInstance );
    _Module.m_hInstResource = LoadLibrary( _T("shell32.dll") );
    MSGBOXPARAMS mbp; ZeroMemory( &mbp, sizeof(mbp) );
    mbp.cbSize = sizeof(mbp);
    mbp.dwLanguageId = GetSystemDefaultLangID();
    mbp.dwStyle = MB_USERICON;
    mbp.hInstance = _Module.GetResourceInstance();
    mbp.lpszCaption = _T("Hello");
    mbp.lpszIcon = MAKEINTRESOURCE( 44 );
    mbp.lpszText = _T("Hello, World!");
    MessageBoxIndirect( &mbp );
    FreeLibrary( _Module.m_hInstResource );
    _Module.m_hInstResource = NULL;
    _Module.Term();
    return 0;
}

此範例展示修改 m_hInstResource 使用外部資源。WTL 繼承 CComModule 派生 CAppModule,更適合應用程式開發,詳見 WTL atlapp.h。

「貌合神離」:ATL 3.0 與 7.0 的異同

  • ATL 3.0:CComModule 直接繼承 _ATL_MODULE。
  • ATL 7.0:CComModule 經歷繼承鏈,更具 COM 風味(ModuleInstance/ResourceInstance 可作 COM 屬性用 get/put)。
  • ATL 7.0 atlbase.h 含更多 COM 開發工具類,與本書無關,略過。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved