Win32API+WinRT+WinUI 杂揉
实在看不惯 WinUI 和 C# 紧紧地绑在一起,于是乎查了很多微软的文档,也上网搜了一下,整出个 Win32API、WinRT、WinUI 三者杂揉在一起的简单程序。
功能:显示 WinUI 弹出式菜单。
特点:无需像此前 UWP 需要有 CoreWindow 才能工作的要求,也不需要打包成 Package 运行。
注:下面是采用 Consume APIs 的方式,至于创作模式(使用 Xaml),要复杂得多,可参考 微软文档 或 示例 。
#include <SDKDDKVer.h>
#include <windows.h>
#include <collection.h>
#include <shobjidl.h>
#include <ppltasks.h>
#include <iostream>
#include <winrt/Windows.Foundation.Collections.h>
#pragma comment(lib, "windowsapp")
using namespace Concurrency;
using namespace Platform;
using namespace Windows;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI;
using namespace Windows::UI::Core;
using namespace Windows::UI::Popups;
void winui_popup_menu_test(HWND hwnd)
{
auto menu = ref new PopupMenu();
IInitializeWithWindow* pInitializeWithWindow = NULL;
reinterpret_cast<::IUnknown*>(menu)->QueryInterface(IID_IInitializeWithWindow, (LPVOID*)(&pInitializeWithWindow));
pInitializeWithWindow->Initialize(hwnd);
pInitializeWithWindow->Release();
menu->Commands->Append(ref new UICommand("Item 1", nullptr, PropertyValue::CreateInt32(1)));
menu->Commands->Append(ref new UICommandSeparator());
menu->Commands->Append(ref new UICommand("Item 2", nullptr, PropertyValue::CreateInt32(2)));
menu->Commands->Append(ref new UICommand("Item 3", nullptr, PropertyValue::CreateInt32(3)));
Rect rectContent(100, 100, 200, 500);
create_task(menu->ShowForSelectionAsync(rectContent)).then([hwnd](IUICommand^ command)
{
if (command != nullptr)
{
int const id = safe_cast<IBox<int>^>(command->Id)->Value;
std::cout << "Item " << id << " selected" << std::endl;
}
else
{
std::cout << "Context menu dismissed" << std::endl;
}
SendMessage(hwnd, WM_QUIT, 0, 0);
});
std::cout << "Context menu shown" << std::endl;
}
static UINT msg_test = 0;
static LRESULT CALLBACK MainWndProc(HWND hWnd, UINT umsg, WPARAM wParam, LPARAM lParam)
{
if(umsg == msg_test || umsg == WM_QUIT)
{
if(umsg == msg_test)
winui_popup_menu_test(hWnd);
else
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, umsg, wParam, lParam);
}
int main(int argc, char **argv)
{
winrt::init_apartment(winrt::apartment_type::single_threaded);
WNDCLASSEX wcApp;
ZeroMemory(&wcApp, sizeof(wcApp));
wcApp.lpszClassName = "test";
wcApp.hInstance = GetModuleHandle(NULL);
wcApp.lpfnWndProc = MainWndProc;
wcApp.cbSize = sizeof(wcApp);
RegisterClassEx(&wcApp);
HWND hWnd = CreateWindowExA(0, "test", "test", WS_DISABLED, 0, 0, 500, 500, NULL, NULL, GetModuleHandle(NULL), NULL);
msg_test = RegisterWindowMessage("MY_TEST");
PostMessageA(hWnd, msg_test, 0, 0);
MSG message;
while(GetMessage(&message, nullptr, 0, 0))
{
DispatchMessage(&message);
}
winrt::clear_factory_cache();
winrt::uninit_apartment();
return 0;
}