Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: C++-класс для окна и WM_GETMINMAXINFO  (Прочитано 10626 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Sharp
Гость
« : 15-03-2006 21:24 » 

Пишу C++-класс для окна, оконная процедура выглядит так:
Код:
	static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
if(uMsg == WM_NCCREATE){
SetWindowLong(hwnd, GWL_USERDATA, (LONG)((LPCREATESTRUCT)lParam)->lpCreateParams);
}

WqWindow *pWindow;
pWindow = (WqWindow *)GetWindowLong(hwnd, GWL_USERDATA);

return pWindow->WndProc(hwnd, uMsg, wParam, lParam);
}
Хочу добавить метод класса, устанавливающий параметры для обработки сообщения WM_GETMINMAXINFO, но оно приходит раньше, чем статическая WindowProc получит возможность узнать указатель на объект, переменные которого надо запихать в MINMAXINFO, т.е. раньше WM_NCCREATE.
Как мне это сделать?

Пока мой вариант выглядит так: перед CreateWindowEx помещать переменные, нужные для обработки WM_GETMINMAXINFO, в глобальную структуру, а в WindowProc из этой глобальной структуры извлекать. А чтобы кто-нибудь из другого треда не поменял эту глобальную структуру, обернуть ее заполнение и CreateWindowEx в критическую секцию. Но мне кажется, что это криво.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 16-03-2006 05:11 » 

наверное так

if(uMsg == WM_GETMINMAXINFO)
{
   static bool bWasHere=false;
   if(!bWasHere)
   {
      bWasHere=true;
      //сохранить данные в специальных мемберах класса
   }
)

}

if(uMsg == WM_NCCREATE)
{
   ...
« Последнее редактирование: 16-03-2006 05:14 от Алексей1153 » Записан

Sharp
Гость
« Ответ #2 : 16-03-2006 06:05 » 

Цитата
//сохранить данные в специальных мемберах класса
Доступ к членам класса из обработчика WM_GETMINMAXINFO невозможен.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 16-03-2006 06:12 » 

хорошо, в классе WqWindow определи структуру X для данных, а в начале WindowProc() - создай экземпляр
WqWindow::X tempX;

заполни его, а потом

...
WqWindow *pWindow;
pWindow = (WqWindow *)GetWindowLong(hwnd, GWL_USERDATA);
pWindow->x=tempX;

если опять статик не пустит, может попробовать передать через сообщение окну pWindow ?
Записан

Sharp
Гость
« Ответ #4 : 16-03-2006 11:31 » 

Код:
pWindow = (WqWindow *)GetWindowLong(hwnd, GWL_USERDATA);
вернет NULL или еще чего похуже, т.к. эти данные заполняются только по WM_NCCREATE, а он приходит позже. Текущее решение:
Код:
int WqWindow_mmi_minW, WqWindow_mmi_minH, WqWindow_mmi_maxW, WqWindow_mmi_maxH;
CRITICAL_SECTION WqWindow_mmi_cs;
...
void setMinMaxInfo(int minW, int minH, int maxW, int maxH){ ... }

HWND Create(){
EnterCriticalSection(&WqWindow_mmi_cs);

WqWindow_mmi_maxW = mmi_maxW; WqWindow_mmi_maxH = mmi_maxH;
WqWindow_mmi_minW = mmi_minW; WqWindow_mmi_minH = mmi_minH;

hWnd = CreateWindowEx(NULL, "WqMainWindow", Caption.c_str(), WS_OVERLAPPEDWINDOW,
startPos.left, startPos.top, startPos.right, startPos.bottom,
NULL, NULL, hInstance, NULL);

LeaveCriticalSection(&WqWindow_mmi_cs);
...
}

static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){

if(uMsg == WM_GETMINMAXINFO){
if(WqWindow_mmi_maxW != -1) ((MINMAXINFO *)lParam)->ptMaxTrackSize.x = WqWindow_mmi_maxW;
if(WqWindow_mmi_maxH != -1) ((MINMAXINFO *)lParam)->ptMaxTrackSize.y = WqWindow_mmi_maxH;
if(WqWindow_mmi_minW != -1) ((MINMAXINFO *)lParam)->ptMinTrackSize.x = WqWindow_mmi_minW;
if(WqWindow_mmi_minH != -1) ((MINMAXINFO *)lParam)->ptMinTrackSize.y = WqWindow_mmi_minH;
return 0;
}

if(uMsg == WM_NCCREATE){
MessageBox(0, "WM_NCCREATE", "Message", MB_ICONASTERISK);
SetWindowLong(hwnd, GWL_USERDATA, (LONG)((LPCREATESTRUCT)lParam)->lpCreateParams);
}

WqWindow *pWindow;
pWindow = (WqWindow *)GetWindowLong(hwnd, GWL_USERDATA);

return pWindow->WndProc(hwnd, uMsg, wParam, lParam);
}
Оно работает, но мне не нравится Улыбаюсь
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #5 : 16-03-2006 13:22 » new

Sharp, Создание окна ты можеш сам самостоятельно проконтролировать. Поэтому в принципе первый посыл WM_GETMINMAXINFO можно игнорировать. Я сделал WndProc таким образом:
Код:
TWindow *TWindow::GetData(const HWND hwnd)
{
return (TWindow *) GetWindowLong(hwnd,GWL_USERDATA);
}

void TWindow::SetData(const HWND hwnd)
{
SetWindowLong(hwnd, GWL_USERDATA, (LONG) this);
}

LRESULT CALLBACK TWindow::WndProc(HWND hwnd, UINT Message,  WPARAM wParam, LPARAM lParam)
{
TWindow *temp;
if (Message == WM_NCCREATE)
     temp =(TWindow* ) (((LPCREATESTRUCT) lParam)->lpCreateParams);
else temp=GetData(hwnd);
if (temp !=NULL) return temp->WProc(hwnd,Message,wParam,lParam);
return 0;
}
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines