Radek Chalupa   konzultace a školení programování, vývoj software na zakázku

Windows desktop aplikace s využitím ATL

1.1.2015

I když knihovna ATL (součást vývojového nástroje Microsoft Visual C++) byla v prvopočátku vyvinuta pro jiné účely (ISAPI a také vytváření efektivních a výkonných COM objektů a ActiveX prvků (což jsou samozřejmě také COMy), lze ji (zejména od verze 7 která byla vydána s Visual Studiem .NET 2002) velmi efektivně a výhodně použít také pro tvorbu "obyčejných" Win32 aplikací, které nemají s technologií COM nic společného. Následující zdrojový kód je KOMPLETNÍ kód win 32 aplikace založené na dialogovém okně a ActiveX prvkem "Webový prohlížeč". Při spuštění (v obsluze zprávy WM_INITDIALOG) je pak zobrazena zvolené webová stránka. Kromě tohoto zdrojového souboru (.cpp) obsahuje projekt pak samozřejmě už jen resource skript s jediným dialogem. Takovýto projekt win32 aplikace využívající ATL lze vytvořit v zásadě dvojím způsobem. Buď vytvoříme nový projekt typu ATL projekt -> Executable (.exe) a "vyházíme" z něj vše co wizard vygeneroval jako základ pro podporu COM objektů (podrobněji se to můžete naučit v tomto školení), nebo (což je v tomto případě jednodušší) založíme prázdný win32 projekt (exe) a přidáme do něj jeden zdrojový soubor, do něhož napíšeme/opíšeme/zkopírujeme následující kód. Kromě toho přidáme do prostředků (resources) dialog obsahující tlačítko OK a ActiveX prvek "Webový prohlížeč společnosti Microsoft.
#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
#define _WIN32_WINDOWS 0x0410
#define _WIN32_IE 0x0500
#define _ATL_APARTMENT_THREADED
#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#define _ATL_NO_COM_SUPPORT
#define _INC_WINDOWSX

#include "resource.h"

#include <atlbase.h>
#include <atlcom.h>
#include <atlhost.h>

using namespace ATL;

class DlgHlavni : public CAxDialogImpl< DlgHlavni >
{
public:
enum { IDD = IDD_HLAVNI };
CAxWindow2 axWnd;
CComPtr webBrowser;

BEGIN_MSG_MAP(DlgNastaveni)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
COMMAND_HANDLER(IDOK, BN_CLICKED, OnKonec)
COMMAND_HANDLER(IDCANCEL, BN_CLICKED, OnKonec)
CHAIN_MSG_MAP(CAxDialogImpl)
END_MSG_MAP()

LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
CAxDialogImpl::OnInitDialog(uMsg, wParam, lParam, bHandled);
axWnd = GetDlgItem(IDC_EXPLORER);

HRESULT hr;
hr = axWnd.QueryControl(&webBrowser);
if (hr != S_OK)
EndDialog(IDCANCEL);
webBrowser->Navigate(L"http://www.radekchalupa.cz", NULL, NULL, NULL, NULL);
return 1;
}

LRESULT OnKonec(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
EndDialog(wID);
return 0;
}
};

class Aplikace : public CAtlExeModuleT< Aplikace >
{
public:
DECLARE_LIBID(LIBID_ATLLib)

HRESULT Aplikace::PreMessageLoop(int nShowCmd)
{
CAtlExeModuleT::PreMessageLoop(nShowCmd);
Lock();
DlgHlavni().DoModal();
Unlock();
return S_FALSE;
}
};

Aplikace _aplikace;

extern "C" int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nShowCmd)
{
return _aplikace.WinMain(nShowCmd);
}