WinUi로 WndProc이용하여 윈도우 메시지 처리하기
WinUi로는 WndProc을 쓸 수 없다. 윈도우 메시지를 처리하려면 SetWindowLong을 이용해 메시지를 가로채 처리해야 한다.
Changes an attribute of the specified window.
SetWindowLongA function (winuser.h)
SetWindowLongA는 앤시 버전이고 SetWindowLongW는 유니코드 버전이다. SetWindowLong은 두 버전 가운데 하나를 자동으로 선택하는 alias다. 따라서 SetWindowLong는 검색해 봐야 나오지 않는다.
DllImport의 EntryPoint에는 SetWindowLong를 설정해도 작동하지만 LoadLibrary는 그렇지 않다. A/W를 특정해야 한다.
The method name or EntryPoint should be the exact spelling of the entry point name.
Source generation for platform invokes
LoadLibrary를 쓸 때에는 SetWindowLongA/W와 SetWindowLongPtrA/W도 구별하여 전자는 x86에 후자는 x64에 써야 한다.
public sealed partial class MainWindow : Window
{
delegate nint WndProcDelegate(nint hWnd, uint msg, nint wParam, nint lParam);
nint Handle;
WndProcDelegate WndProc_;
nint OriginalPointer;
int GWLP_WNDPROC = -4;
public MainWindow()
{
InitializeComponent();
Handle = WindowNative.GetWindowHandle(this);
WndProc_ = WndProc;
nint pointer = Marshal.GetFunctionPointerForDelegate(WndProc_);
OriginalPointer = SetWindowLong(Handle, GWLP_WNDPROC, pointer);
}
// x86
[LibraryImport("user32.dll", EntryPoint = "SetWindowLongA")] private static partial nint SetWindowLong(nint hWnd, int nIndex, nint dwNewLong);
[LibraryImport("user32.dll", EntryPoint = "GetWindowLongA")] private static partial nint GetWindowLong(nint hWnd, int nIndex);
[LibraryImport("user32.dll", EntryPoint = "CallWindowProcA")] private static partial nint CallWindowProc(nint lpPrevWndFunc, nint hWnd, uint msg, nint wParam, nint lParam);
nint WndProc(nint hWnd, uint msg, nint wParam, nint lParam)
{
// do something
return CallWindowProc(OriginalPointer, hWnd, msg, wParam, lParam);
}
}
x86 전용인 ls증권 api를 이용하느라 위와 같이 했다.