RATL: Alternative technology for ATL

当サイトではアフィリエイト広告を利用しております。

ReactOS

What’s RATL?

We will explain Independent ReactOS ATL, commonly known as RATL, which is an alternative technology to Active Template Library (ATL).

RATL was developed as a subset of ATL on a Windows-like OS called ReactOS. RATL has the basic functionality of ATL.

How to use RATL?

First, let’s download katahiromz/RATL from GitHub.

git clone https://github.com/katahiromz/RATL

There are many ATL headers listed in $(RATL)/include/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

It’s not 100% compatible, but it feels like it might be usable to some extent.

Now, let’s try out the sample. Copy AtlDialogApp from the RATL samples folder to another suitable location.

Enable AtlDialogApp to use Git.

git init
git add -A
git commit -m "first commit"

Next, let’s make RATL available as a Git submodule.

git submodule add https://github.com/katahiromz/RATL

This will create a folder called RATL inside AtlDialogApp. Now, let’s build AtlDialogApp using RosBE (ReactOS build environment).

cd AtlDialogApp
cmake -G Ninja .
ninja

This will build AtlDialogApp.

Now you can create Win32/ATL applications with RosBE using RATL. I didn’t use Visual Studio in this time. It is now independent from Visual Studio. Congrats!

Source code

Below is the source code of 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;
}

Looking at the source, CRegKey and CDialogImpl can be used properly.

Projects using RATL

Copyright and License of RATL

  • Copyright © ReactOS Development Team.
  • LGPL 2.1 and later.

コメント

タイトルとURLをコピーしました