Создайте родное окно окна в JNA и некоторые GetWindowlong с GWL_WNDPROC
-
27-09-2019 - |
Вопрос
Добрый день,
Я использовал JNA некоторое время, чтобы взаимодействовать с API Windows, и теперь я застрял при создании окна. Насколько я сделал следующее: 1. Создал дочернее окно существующего окна и получил до него действительный обработчик. 2. Понял, что каждое окно в Windows имеет неконкурнтную петлю сообщения. 3. Понял, что лучший способ включить в систему моего окна в цикл отправки сообщения - это использовать что-то вроде следующего кода (не мое, но это то, что я тоже буду делать):
final LONG_PTR prevWndProc = new LONG_PTR(User32.INSTANCE.GetWindowLong(hwnd, User32.GWL_WNDPROC)); //this is to obtain a pointer to the WNDPROC of the parent window, which we are going to need later
wndProcCallbackListener = new WndProcCallbackListener()
{
public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam)
{
if (uMsg == WTSAPI.WM_POWERBROADCAST)
{
System.out.println("WM_POWERBROADCAST Event: hWnd="+hwnd+", uMsg="+uMsg+", uParam="+uParam+", lParam="+lParam);
}
else if (uMsg == WTSAPI.WTS_SESSION_CHANGE)
{
System.out.println("WTS_SESSION_CHANGE Event: hWnd="+hwnd+", uMsg="+uMsg+", uParam="+uParam+", lParam="+lParam);
}
//Call the window's actual WndProc so the events get processed.
return User32.INSTANCE.CallWindowProc(prevWndProc, hWnd, uMsg, uParam, lParam);
}
};
//Set the WndProc function to use our callback listener instead of the window's one.
int result = User32.INSTANCE.SetWindowLong(hwnd, User32.GWL_WNDPROC, wndProcCallbackListener);
Тем не менее, моя проблема в том, когда я называю GetWindowlong () для родительского окна (Моя первая строка кода) Я получаю 0 для указателя, который указал, что функция не завершилась успешно. Последующий вызов GetLastaRastror () и быстрой проверки в кодах ошибок дают мне 'Доступ запрещен' ошибка. Это, конечно, логично, поскольку я пытаюсь получить по собственной ветве, чтобы получить доступ к адресу WNDProc другого, но мне было интересно, есть ли какие-либо способы (должно быть, конечно), чтобы обойти это.
Любые указатели? (каламбур)
Решение
Не используйте GetLastaRastror () после вызова JNA. JNA & JNI могут вызывать другие API, которые могут изменить последнюю ошибку. Объявите SetWindowlong с предложением бросает LasterRorexception, как это:
int SetWindowLongA(int hWnd, int nIndex, WndProcCallbackListener dwNewLong)
throws LastErrorException;
Обратите внимание на «a» после имени. Это делает явное использование версии ANSI. Вы также можете использовать SetWindowlongw.
Убедитесь, что ваш обратный вызов реализует как Callback, так и STDCALL. Я предпочитаю максимально использовать примитивные типы, потому что это делает картирование быстро и очевидно для JNA:
public interface WndProcCallbackListener extends Callback, StdCall {
int callback(int hWnd, int Msg, int wParam, int lParam);
}