RATLとは何か
Active Template Library (ATL) の代替技術である、Independent ReactOS ATL、通称RATL(ラトル)について解説します。
RATLは、ReactOSというWindowsライクなOSでATLのサブセットとして開発されました。ATLの基本的な機能がRATLに備わっています。
RATLの使い方
まずは、GitHubからkatahiromz/RATL
をダウンロードしてみましょう。
git clone https://github.com/katahiromz/RATL
$(RATL)/include/atl
にATLのヘッダがたくさん並んでいますね。
- atlalloc.h
- atlbase.h
- atlcoll.h
- atlcom.h
- atlcomcli.h
- atlconv.h
- atlcore.h
- atldef.h
- atlexcept.h
- atlfile.h
- atlimage.h
- atlmem.h
- atlpath.h
- atlsimpcoll.h
- atlsimpstr.h
- atlstr.h
- atlsync.h
- atltime.h
- atltrace.h
- atltypes.h
- atlwin.h
- cstringt.h
- statreg.h
100%の互換性とまではいきませんが、ある程度使えるかも、と言った感じです。
では、早速サンプルを試してみましょう。RATLのsamples
フォルダのAtlDialogApp
をどこか別の適当な場所にコピーしましょう。
AtlDialogApp
でGitを使えるようにします。
git init
git add -A
git commit -m "first commit"
次に、RATLをGitサブモジュールとして使えるようにします。
git submodule add https://github.com/katahiromz/RATL
これでRATL
というフォルダがAtlDialogApp
内部に作られます。ではReactOSのビルド環境のRosBEでAtlDialogApp
をビルドして見ましょう。
cd AtlDialogApp
cmake -G Ninja .
ninja
これでAtlDialogApp
がビルドされます。
これでRATLを使ってRosBEでWin32/ATLアプリが作れるようになりました。Visual Studioは使っていません。これでVisual Studioから独立できました。めでたしめでたし。
ソースコード
以下はAtlDialogApp
のソースコードです。
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include "resource.h"
//////////////////////////////////////////////////////////////////////////////////////////////////
class CMyExeModule : public ATL::CAtlExeModuleT<CMyExeModule>
{
};
CMyExeModule g_my_exe;
//////////////////////////////////////////////////////////////////////////////////////////////////
class CMainWindow : public CDialogImpl<CMainWindow, CWindow>
{
public:
enum { IDD = IDD_MAIN };
CMainWindow();
virtual ~CMainWindow();
VOID ResetSettings();
BOOL LoadSettings();
BOOL SaveSettings();
BEGIN_MSG_MAP(CMainWindow)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_COMMAND, OnCommand)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
END_MSG_MAP()
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MAINICON));
HICON hIconSm = (HICON)LoadImage(
GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON,
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
SendMessage(WM_SETICON, ICON_BIG, (LPARAM)hIcon);
SendMessage(WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
return 0;
}
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
return 0;
}
BOOL OnOK()
{
// TODO: Do something
return TRUE;
}
LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
switch (LOWORD(wParam))
{
case IDOK:
if (OnOK())
{
EndDialog(IDOK);
}
break;
case IDCANCEL:
EndDialog(IDCANCEL);
break;
}
return 0;
}
LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
PAINTSTRUCT ps;
if (HDC hDC = BeginPaint(&ps))
{
RECT rc;
GetClientRect(&rc);
::MoveToEx(hDC, rc.left, rc.top, NULL);
::LineTo(hDC, rc.right, rc.bottom);
::MoveToEx(hDC, rc.right, rc.top, NULL);
::LineTo(hDC, rc.left, rc.bottom);
UINT uFormat = DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX;
::DrawText(hDC, TEXT("Hello, RATL"), -1, &rc, uFormat);
EndPaint(&ps);
}
return 0;
}
};
CMainWindow::CMainWindow()
{
}
CMainWindow::~CMainWindow()
{
}
VOID CMainWindow::ResetSettings()
{
// TODO: Reset settings
}
BOOL CMainWindow::LoadSettings()
{
ResetSettings();
CRegKey appKey;
LONG error;
error = appKey.Open(HKEY_CURRENT_USER, TEXT("Software\\ReactOS\\AtlDialogApp"));
if (error)
return FALSE;
// TODO: Load settings
return TRUE;
}
BOOL CMainWindow::SaveSettings()
{
CRegKey companyKey, appKey;
LONG error;
error = companyKey.Create(HKEY_CURRENT_USER, TEXT("Software\\ReactOS"));
if (error)
return FALSE;
error = appKey.Create(companyKey, TEXT("AtlDialogApp"));
if (error)
return FALSE;
// TODO: Save settings
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
INT WINAPI
WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
INT nCmdShow)
{
InitCommonControls();
CMainWindow mainWnd;
mainWnd.LoadSettings();
if (mainWnd.DoModal(NULL, 0) == IDOK)
{
// TODO: Do something
}
mainWnd.SaveSettings();
return 0;
}
ソースを見るとCRegKey
もCDialogImpl
もちゃんと使えています。
RATLを使っているプロジェクト
RATLの著作権とライセンス
- Copyright © ReactOS 開発チーム。
- LGPL 2.1以降。
コメント