Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > TRACKBAR_CLASS в строке состояния


Автор: MironenkoDima 12.6.2013, 03:39
Добрый день.
Никак не получается заставить работать регулятор TRACKBAR_CLASS.
Этот регулятор нужен в строке состояния. (будет отвечать за масштаб)
Создаётся без каких-либо проблем, все начальные параметры так же задаются нормально. Да и ползунок передвигается всеми возможными способами.

Не могу понять, где обрабатывать сообщения? Родительское окно для него - строка состояния. А для неё обработчика нету. или..?

Код

case WM_CREATE:
{
    . . . . .
    hStatus = CreateStatusWindow(WS_CHILD|WS_VISIBLE, "Режим просмотра", hWnd, ID_STATUS);
    int temp = wwind/2;
    pParts[0] = wwind - temp-35; pParts[1] = wwind - temp+35; pParts[2] = -1;
    SendMessage(hStatus, SB_SETMINHEIGHT, 28, 0);
    SendMessage(hStatus, SB_SETPARTS, 3, (LPARAM)pParts);
    SendMessage(hStatus, SB_SETTEXT, 1, (LPARAM)"(0, 0)");
    
    RECT rect;
    SendMessage(hStatus, SB_GETRECT, 2, (LPARAM)&rect);
    hSliderScale = CreateWindow(TRACKBAR_CLASS, NULL, WS_CHILD|WS_VISIBLE|TBS_AUTOTICKS|TBS_BOTH, rect.left+50, rect.top+1, 150, 26, hStatus, (HMENU)ID_SLIDER, GetModuleHandle(NULL), NULL);
    SendMessage(hSliderScale, TBM_SETRANGE, TRUE, MAKELPARAM(10,1000));
    SendMessage(hSliderScale, TBM_SETPOS, TRUE, Data->scale);
    SendMessage(hSliderScale, TBM_SETLINESIZE, 0, 10);
    SendMessage(hSliderScale, TBM_SETPAGESIZE, 0, 50);
    SendMessage(hSliderScale, TBM_SETTICFREQ, 50, 0);
    . . . . .
}

Автор: Earnest 12.6.2013, 05:24
Что значит - нет обработчика? Напиши. 
Любые обработчики можно добавить в любое окно путем изменения оконной процедуры.

Автор: MironenkoDima 12.6.2013, 11:26
Ну тут я сделал слишком "громкое" заявление в силу своей неграмотности. Извините.
Есть ли возможность обработать сообщения более обобщённым способом?

Автор: Earnest 13.6.2013, 08:21
Так это и есть самый обобщенный способ - сабклассинг то есть.
Сообщение обычно посылаются родителю, вот он и должен их обрабатывать.
Однако нельзя не согласиться, что обработка сообщений от трэкбара в строке состояния не очень логична с точки зрения логики приложения.
Я бы сделала так: сабклассила строку состояния так, что все нотификации от трэкбара просто пересылаются главному окну. Кроме того, туда же (т.е. в новую процедуру строки состояния) нужно засунуть создание самого трэкбара, избавив главное окно от ненужных подробностей. 

Автор: GremlinProg 13.6.2013, 09:53
Есть вариант обойтись без сабклассинга: нужно завести 2 диалоговых ресурса. В первом размещается основное окно, а второй оформляется как дочерний статусбар, на котором можно размещать трекбар и спокойно обрабатывать в этом диалоге уведомления трекбара (WM_COMMAND и WM_NOTIFY). Тогда второй диалог нужно создать на первом, используя функцию CreateDialog

Добавлено через 14 минут и 2 секунды
но если смотреть в корень, то функционал управления диалогами реализуется на суперклассинге, так что общая логика Earnest работает и тут.

Автор: MironenkoDima 13.6.2013, 15:59
Спасибо за ответы!
Почитал про сабклассинг, всё получилось!

Как-то так:
Код

WNDPROC onStandartStatusBar;
LRESULT CALLBACK onStatusBar(HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_CREATE:
        {
            . . .
            hStatus = CreateStatusWindow(WS_CHILD|WS_VISIBLE, "Режим просмотра", hWnd, ID_STATUS);
            . . .
            onStandartStatusBar = (WNDPROC)SetWindowLong(hStatus, GWL_WNDPROC, (LONG)onStatusBar);
            . . .
        }
    }
}

LRESULT CALLBACK onStatusBar(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (msg == WM_HSCROLL)
    {
        Data->scale = SendMessage(hSliderScale, TBM_GETPOS, 0, 0);
        InvalidateRect(GetParent(hWnd), NULL, TRUE);
        return 0;
    }
    return CallWindowProc(onStandartStatusBar, hWnd, msg, wParam, lParam);
}


Цитата(Earnest @  13.6.2013,  08:21 Найти цитируемый пост)
Кроме того, туда же (т.е. в новую процедуру строки состояния) нужно засунуть создание самого трэкбара, избавив главное окно от ненужных подробностей. 

Хотел реализовать и это, но не вышло. Трэкбар не создаётся. Обрабатывал сообщение WM_CREATE и в нём создавал.
Можете направить на верное решение, пожалуйста?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)