Я зарегистрировал обратный вызов через: SetWindowLongW(hWindow, GWL_WNDPROC, (LONG)WindowCallback);
Я получаю сообщения там без проблем. У меня есть() код стиля внутри обратного вызова, который выглядит так:
if (MSG == 1)
{
*boolptr = true;
...
} else if(MSG == 2) {
if (*boolptr == true)
return;
// do stuff
}
Переменные определяются так (globaly, под #includes right..)
volatile bool boolVar = false; volatile bool* volatile boolptr = &boolVar;
Если я ожидаю, что * boolptr будет TRUE в main(), все будет в порядке, но если я буду ждать его внутри того же callback, где он должен измениться, он не работает. Очевидно, я не понимаю некоторые понятия здесь, поэтому я прошу помощи или объяснения, почему она не работает.
MSG со значением 2 всегда начинается первым, а затем после некоторой обработки MSG со значением 1. Через какое-то время происходит то же самое, но я не хочу делать такую же обработку и отходы процессорных циклов, поэтому мне нужно знать, MSG [1] следует за ним и просто возвращается. Я надеюсь ты понимаешь меня.
Благодарю!
Ваше описание оставляет много деталей, но я думаю, что понимаю, чего вы хотите. Последний параметр функции API CreateWindow() может использоваться для передачи указателя на ваш обратный вызов на некоторую внешнюю переменную:
// MAKE SURE this variable stays in scope throughout the lifetime of your window !
// Make it global or static
bool myVar;
// let create an overlapped window of some class with size 400 x 300
HWND hWnd = CreateWindow("My class name", "My Title",
WS_VISIBLE | WS_BORDER| WS_OVERLAPPED | WS_CAPTION |
WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
0,0, 400, 300, NULL, NULL, GetModuleHandle(NULL), &myVar);
Затем в обратном вызове вы получаете доступ к нему в сообщении WM_CREATE:
// ... start of your callback
// get a pointer to your variable here and use it in all messages
// *except* WM_CREATE that sets it during window instance creation
bool *pMyVar = (bool *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
switch(uMsg)
{
case WM_CREATE:
{
// get your pointer from the CREATESTRUCT passed in
// and store it in the user data area of your window class
// note: your WNDCLASS should have its cbWndExtra = sizeof(void *);
CREATESTRUCT *pC = (CREATESTRUCT *)lParam;
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG)pC->lpCreateParams);
// ....
}
break;
case 1 : // VERY bad choice for a message, use WM_USER+1 instead
*pMyVar = true;
break;
// ... rest of your callback
это то, что вы хотели?
EDIT: Хорошо, вот класс, который вы хотели увидеть:
class MyClass
{
public:
MyClass() : _hasRun(false) { }
void DoStuff(HWND hW, UINT uMsg)
{
if (!_hasRun)
{
_hasRun = true;
// ... do your work here, you have the window handle and the message
}
}
private:
bool _hasRun;
};
теперь в вашем основном создайте экземпляр этого класса и сохраните его в статической или глобальной переменной:
MyClass *pC = new MyClass;
затем передайте это обратному вызову, как я показываю в начале, и затем вызываем его всегда. Функция участника DoStuff проверяет сообщение и делает то, что вы хотите, на основе того, что это сообщение, один раз. Даже если вы держите его в глобальном режиме и всегда вызываете это глобальное от обратного вызова, функциональность будет одинаковой.
// ... callback code before you handle any message
pC->DoStuff(hWnd, uMsg);
// ... rest of callback code