Возникла проблема с подклассами в WinUI3 C++C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Возникла проблема с подклассами в WinUI3 C++

Сообщение Anonymous »

У меня возникли проблемы с созданием подклассов в C++, но в C# они работают корректно.
Проблема, с которой я столкнулся: Исключение, возникающее по адресу 0x00007FF9C7231DD4 (user32.dll) в WinUICPPTest.exe: 0xC0000005: местоположение чтения нарушения прав доступа 0xFFFFFFFF9E76E4C0.
После этой строки return CallWindowProc(originalWndProc, hWnd, uMsg, wParam, lParam); >
Вот версия для C++-

Код: Выделить всё

#include "pch.h"
#include "MainWindow.xaml.h"
#if __has_include("MainWindow.g.cpp")
#include "MainWindow.g.cpp"
#endif

#include 

using namespace winrt;
using namespace Microsoft::UI::Xaml;

namespace winrt::WinUICPPTest::implementation
{
static WNDPROC originalWndProc;

static LRESULT CustomWndProc(HWND hWnd, UINT uMsg, INT wParam, INT lParam)
{
switch (uMsg)
{
case WM_HOTKEY: // WM_HOTKEY
if (IsWindowVisible(hWnd) == 0)
{
ShowWindow(hWnd, 5); // SW_SHOW
SetForegroundWindow(hWnd);
}
else
{
ShowWindow(hWnd, 0);  // SW_HIDE
}
break;
}

// Call the original window procedure for any unhandled messages
return CallWindowProc(originalWndProc, hWnd, uMsg, wParam, lParam);
}

MainWindow::MainWindow()
{
// Xaml objects should not call InitializeComponent during construction.
// See https://github.com/microsoft/cppwinrt/tree/master/nuget#initializecomponent

auto windowNative{ this->m_inner.as() };
HWND hwnd{ 0 };
windowNative->get_WindowHandle(&hwnd);

// Register the hotkey
RegisterHotKey(hwnd, 1, MOD_ALT, VK_F12);

// Subclass the window procedure
SubclassWndProc(hwnd);
}

int32_t MainWindow::MyProperty()
{
throw hresult_not_implemented();
}

void MainWindow::MyProperty(int32_t /* value */)
{
throw hresult_not_implemented();
}

void MainWindow::SubclassWndProc(HWND hwnd)
{
// Store the original window procedure
originalWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC);

// Subclass the window procedure
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)CustomWndProc);
}

void MainWindow::RegisterF12HotKey(HWND hWnd)
{
// Register Alt + F12 as a hotkey
RegisterHotKey(hWnd, 1, MOD_ALT, VK_F12);
}
}
А вот версия C#

Код: Выделить всё

namespace WinUITestApp
{
public sealed partial class MainWindow :  Window
{
private delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
private static WndProcDelegate customWndProcDelegate;
private static IntPtr originalWndProc = IntPtr.Zero;

public MainWindow()
{
this.InitializeComponent();

// Subclass the window procedure
customWndProcDelegate = new WndProcDelegate(CustomWndProc);
IntPtr hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
SubclassWndProc(hwnd);
RegisterF12HotKey(hwnd);

if (this.AppWindow != null)
{
// Get the presenter and modify its properties
var presenter = this.AppWindow.Presenter as OverlappedPresenter;
if (presenter != null)
{
presenter.IsMaximizable = false;
presenter.IsMinimizable = false;
presenter.IsResizable = true;
}
}

}

// Import the necessary user32.dll functions
[DllImport("user32.dll", SetLastError = true, EntryPoint = "SetWindowLongPtr")]
private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

[DllImport("user32.dll", SetLastError = true, EntryPoint = "SetWindowLong")]
private static extern IntPtr SetWindowLong32(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

[DllImport("user32.dll", SetLastError = true, EntryPoint = "GetWindowLongPtr")]
private static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);

[DllImport("user32.dll", SetLastError = true, EntryPoint = "GetWindowLong")]
private static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);

private const int GWL_WNDPROC = -4;

private static void SubclassWndProc(IntPtr hwnd)
{
// Store the original window procedure pointer
originalWndProc = GetWindowLongPtr(hwnd, GWL_WNDPROC);

// Set the new window procedure (custom one)
SetWindowLongPtr(hwnd, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(customWndProcDelegate));
}

private static IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex)
{
if (IntPtr.Size == 8) // 64-bit
{
return GetWindowLongPtr64(hWnd, nIndex);
}
else // 32-bit
{
return GetWindowLong32(hWnd, nIndex);
}
}

private static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
{
if (IntPtr.Size == 8) // 64-bit
{
return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
}
else // 32-bit
{
return SetWindowLong32(hWnd, nIndex, dwNewLong);
}
}

private static IntPtr CustomWndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
{
switch (uMsg)
{
case 0x0312: // WM_HOTKEY
if (IsWindowVisible(hWnd) == 0)
{
ShowWindow(hWnd, 5); // SW_SHOW
SetForegroundWindow(hWnd);
}
else
{
ShowWindow(hWnd, 0);  // SW_HIDE
}
break;
}

// Call the original window procedure for any unhandled messages
return CallWindowProc(originalWndProc, hWnd, uMsg, wParam, lParam);
}

[DllImport("user32.dll")]
private static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

[DllImport("user32.dll", SetLastError = true)]
static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll")]
static extern int IsWindowVisible(IntPtr hWnd);

[DllImport("user32.dll", SetLastError = true)]
static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

private const int MOD_ALT = 0x0001;
private const int VK_F12 = 0x7B;

private void RegisterF12HotKey(IntPtr hWnd)
{
// Register Alt + F12 as a hotkey
RegisterHotKey(hWnd, 1, MOD_ALT, VK_F12);
}
}
}

Подклассы окон должны работать нормально, не вызывая вышеуказанного исключения. Окно должно вызываться при нажатии HotKey.
Я работаю над приложением WinUI3 на C++, но в этом проблема. Я получаю. Я попробовал это в приложении C# WinUI 3, и оно работает правильно.

Подробнее здесь: https://stackoverflow.com/questions/791 ... n-winui3-c
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»