Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Winapi программа получает WM_SIZE лишь однажды 
:(
    Опции темы
Svia
Дата 26.5.2009, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 20.5.2009

Репутация: нет
Всего: нет



Обычная винапишная программа, созданная мастером студии. В WndProc обрабатываю 2 события: WM_SIZE и WM_SIZING. Второе отрабатывает отлично, на каждый чих с изменениями размера выдает информацию. Первое же я получаю лишь при старте программы и впоследствии - ни разу. Насколько я понял msdn это сообщение посылается программе каждый раз когда окно ИЗМЕНИЛО свои размеры. Однако по окончанию дерганья окошка программа это сообщение не получает. Проверим Spy++ - действительно, не получает. Окно создается со стилями CS_HREDRAW | CS_VREDRAW.
PM MAIL   Вверх
GremlinProg
Дата 26.5.2009, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(Svia @  26.5.2009,  21:53 Найти цитируемый пост)
CS_HREDRAW | CS_VREDRAW

это на WM_SIZE не влияет

влиять может опущенный флаг "Отображать содержимое окна при перетаскивании" в свойствах экрана
тогда да: ресайзится только рамка окна, а изменение размеров происходит только при отпускании мыши


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Svia
Дата 26.5.2009, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 20.5.2009

Репутация: нет
Всего: нет



Цитата(GremlinProg @ 26.5.2009,  20:20)
Цитата(Svia @  26.5.2009,  21:53 Найти цитируемый пост)
CS_HREDRAW | CS_VREDRAW

это на WM_SIZE не влияет

влиять может опущенный флаг "Отображать содержимое окна при перетаскивании" в свойствах экрана
тогда да: ресайзится только рамка окна, а изменение размеров происходит только при отпускании мыши

Дело в том, что при отпускании мышки окно НЕ ПОЛУЧАЕТ СООБЩЕНИЕ WM_SIZE, о чем я написал. Будет ли оно его получать в процессе дерганья - мне без разницы. А вот то, что по окончанию этого действия WM_SIZE не прилетает - это напрягает.
PM MAIL   Вверх
GremlinProg
Дата 26.5.2009, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



показывай обработку всех сообщений, чего гадать-то
проблем с приходом WM_SIZE в принципе быть не должно (либо где-то пропущен break, либо перекрыт стандартный функционал)


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Svia
Дата 26.5.2009, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 20.5.2009

Репутация: нет
Всего: нет



Код

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;

    cairo_surface_t*    surface;
    cairo_t*            cr;

    switch (message)
    {
    case WM_CREATE:
        DragAcceptFiles(hWnd, 1);
        break;
    case WM_DROPFILES:
        {
            HDROP fDrop = (HDROP)wParam;
            char fname[MAX_PATH];
            int dropNum = DragQueryFileA(fDrop, -1, fname, MAX_PATH);

            if( dropNum )
            {
                vector<string> files(dropNum);
                for( int i = 0; i < dropNum; ++i )
                {
                    DragQueryFileA(fDrop, i, fname, MAX_PATH);
                    files[ i ] = fname;
                }

                POINT p;
                if( DragQueryPoint(fDrop, &p) )
                {
                    //Dropped in non-client area
                }

                //mgr->OnFilesDropped(p.x, p.y, files);
            }
            DragFinish(fDrop);
        }
        break;
    case WM_PAINT:
        {
            hdc = BeginPaint(hWnd, &ps);
            surface = cairo_win32_surface_create(hdc);
            cr = cairo_create(surface);
            layout->OnDraw(cr);
            cairo_surface_destroy(surface); 

            EndPaint(hWnd, &ps);
        }
        break;
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_LBUTTONDOWN:
        {
            int modifiers = wParam;
            int x = LOWORD(lParam);
            int y = HIWORD(lParam);
            //mgr->OnMouseDown(x, y, modifiers);
        }
        break;
    case WM_MBUTTONUP:
    case WM_RBUTTONUP:
    case WM_LBUTTONUP:
        {
            int modifiers = wParam;
            int x = LOWORD(lParam);
            int y = HIWORD(lParam);
            //mgr->OnMouseUp(x, y, modifiers);
        }
    case WM_KEYDOWN:
        {
            int vkey = (int) wParam;
            //mgr->OnKeyDown(vkey, (int) lParam);
        }
        break;
    case WM_KEYUP:
        {
            int vkey = (int) wParam;
            //mgr->OnKeyDown(vkey, (int) lParam);
        }
        break;
    case WM_WINDOWPOSCHANGED:
        {
            hdc = GetDC(hWnd);
            ReleaseDC(hWnd, hdc);
        }
        break; 
    case WM_SIZE:
        {
            RECT r;
            r.left = r.top = 0;
            r.right = LOWORD(lParam);
            r.bottom = HIWORD(lParam);

            layout->OnSize®;
            SendMessage(hWnd, WM_PAINT,0,0);
        }
        break;
    case WM_SIZING:
        {
            RECT* r = (RECT*) lParam;
            POINT p1 = { r->left, r->top };
            POINT p2 = { r->right, r->bottom };

            ScreenToClient(hWnd, &p1);
            ScreenToClient(hWnd, &p2);

            MyRect r1(0, 0, p2.x + p1.x, p2.y + p1.y);

            layout->OnSize(r1);
            SendMessage(hWnd, WM_PAINT,0,0);
        }
        break;
    case WM_ERASEBKGND: //Here all stubs
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// Global Variables:
HINSTANCE hInst;                                // current instance
TCHAR* szTitle = _T("Hello, Cairo");
TCHAR* szWindowClass = _T("CairoClass");

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

TTLayoutManager*    layout;

void finishApp()
{
    if( layout )
        delete layout;
}

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    atexit(finishApp);

    // TODO: Place code here.
    MSG msg;

    // Initialize global strings
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    TBlock* b = new TBlock(1);
    b->AddSection("Serpentine", 0);
    b->AddSection("Serpentine Lights", 0);
    //b->SetSize(400, 400, 1);
    //b->SetSize(0, 0, 0);

    //layout->GetBlockManager()->AddBlock(b);

    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = 0;
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = 0;
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = 0;

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;

    hInst = hInstance; // Store instance handle in our global variable

    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    if (!hWnd)
    {
        return FALSE;
    }

    layout = new TTLayoutManager(hWnd);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    return TRUE;
}



Добавлено через 2 минуты и 57 секунд
Нужное - начиная с 88 строки

Это сообщение отредактировал(а) Svia - 26.5.2009, 21:13
PM MAIL   Вверх
GremlinProg
Дата 26.5.2009, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



ну да, вот сейчас сразу все понятно - перекрыт функционал
я не рекомендую ни кому использовать форму switch'а, используемую по-умолчанию:
Код

switch( message ){
  case ...
  case ...
  case ...
  default:
    return DefWindowProc(...);
}

это очень неудобная форма, поскольку очень просто не заметить такого рода перекрытия:
Цитата(WM_WINDOWPOSCHANGED @ MSDN)

By default, the DefWindowProc function sends the WM_SIZE and WM_MOVE messages to the window. The WM_SIZE and WM_MOVE messages are not sent if an application handles the WM_WINDOWPOSCHANGED message without calling DefWindowProc. It is more efficient to perform any move or size change processing during the WM_WINDOWPOSCHANGED message without calling DefWindowProc. 

т.е., на WM_WINDOWPOSCHANGED должен быть обязательно вызван DefWindowProc

Svia, я тебе рекомендую привести WndProc к следующему виду:
Код

switch( message ){
  case ...
  case ...
  case ...
}
return DefWindowProc(...);

обрати внимание, это не одно и то же


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Svia
Дата 26.5.2009, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 20.5.2009

Репутация: нет
Всего: нет



Гмм... Спасибо большое. Неочевидная вещь, спасибо, завтра попробую собрать иначе.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0779 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.