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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите перерисовка окон встроенных классов 
V
    Опции темы
yngwie19
Дата 5.3.2009, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Всем привет. Я делаю присер из книги Финогенова. "Основы программирования WIN32" и разбираю один пример, ниже выкладываю его код (всего 2 файлика gui.cpp и gui.h):
gui.cpp
Код

#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include "gui.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE,LPSTR,int)
{
    LPSTR lpszClassName = "MainWindow";
    LPSTR lpszTitle = "Программа 8-3";
    MSG msg;
    WNDCLASS wc = {0};
    
    InitCommonControls();
    
    // Описание и регистрация класса MainWindow
    wc.lpszClassName = lpszClassName;
    wc.hInstance = hInstance;
    wc.lpfnWndProc = MainWindowWndProc;
    wc.hCursor = LoadCursor(NULL,IDC_ARROW);
    wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    wc.hbrBackground = GetStockBrush(LTGRAY_BRUSH);
    
    if(!RegisterClass(&wc))
        MessageBox(NULL,"Класс MainWindow не зарегестрирован","Ошибка",MB_OK | MB_ICONSTOP);

    // Описание и регистрация класса GraphWindow
    wc.lpszClassName = lpszGraphClassName;
    wc.lpfnWndProc = GraphWndProc;
    wc.hbrBackground = GetStockBrush(WHITE_BRUSH);
    
    if(!RegisterClass(&wc))
        MessageBox(NULL,"Класс GraphWindow не зарегестрирован","Ошибка",MB_OK | MB_ICONSTOP);
    
    HWND hwnd = CreateWindow(lpszClassName,lpszTitle,WS_SYSMENU | WS_CAPTION,10,10,500,277,HWND_DESKTOP,NULL,hInstance,NULL);
    ShowWindow(hwnd,SW_SHOWNORMAL);
    
    while(GetMessage(&msg,NULL,0,0))
        DispatchMessage(&msg);
    
    return 0;
}

// Функции класса MainWindow
LRESULT CALLBACK MainWindowWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        HANDLE_MSG(hwnd,WM_CREATE,MainWindowOnCreate);
        HANDLE_MSG(hwnd,WM_HSCROLL,MainWindowOnHScroll);
        HANDLE_MSG(hwnd,WM_CTLCOLORSTATIC,MainWindowOnCtlColorStatic);
        HANDLE_MSG(hwnd,WM_DESTROY,MainWindowOnDestroy);
        default:
            return DefWindowProc(hwnd,msg,wParam,lParam);
    }
}

BOOL MainWindowOnCreate(HWND hwnd, LPCREATESTRUCT)
{
    // Создание окна для вывода графика
    CreateWindow(lpszGraphClassName,NULL,WS_CHILD | WS_VISIBLE | WS_BORDER,10,10,220,200,hwnd,NULL,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL);
    
    // Создание окна для вывода текста для TrackBar
    CreateWindow("STATIC","Отношение частот по осям",WS_CHILD | WS_VISIBLE,270,30,180,15,hwnd,NULL,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL);
    
    // Создание окна TrackBar
    hwndTrack = CreateWindow(TRACKBAR_CLASS,NULL,WS_CHILD | WS_VISIBLE | TBS_AUTOTICKS,250,55,210,30,hwnd,NULL,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL);
    SendMessage(hwndTrack,TBM_SETRANGE,TRUE,MAKELPARAM(1,10));
    SendMessage(hwndTrack,TBM_SETPAGESIZE,0,1);
    SendMessage(hwndTrack,TBM_SETPOS,TRUE,1);
    
    // Создание окна вывода нумерации под TrackBar
    CreateWindow("STATIC","1   2   3   4   5   6   7   8   9  10",WS_CHILD | WS_VISIBLE,260,85,220,22,hwnd,NULL,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL);
    
    // Создание окна вывода текста для ScrollBar
    CreateWindow("STATIC","Сдвиг фаз в градусах",WS_CHILD | WS_VISIBLE,280,130,200,22,hwnd,NULL,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL);
    
    // Создание окна ScrollBar для изменения фазы
    sinfo.cbSize = sizeof(SCROLLINFO);
    sinfo.fMask = SIF_ALL;
    sinfo.nMin = 0;
    sinfo.nMax = 180;
    sinfo.nPage = 18;
    sinfo.nPos = 0;
    
    hwndScroll = CreateWindow("SCROLLBAR",NULL,WS_CHILD | WS_VISIBLE,260,160,200,20,hwnd,NULL,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL);
    SetScrollInfo(hwnd,SB_CTL,&sinfo,TRUE);
    
    // Создание окна надписи под шкалой Scroll "0" и 180
    CreateWindow("STATIC","0",WS_CHILD | WS_VISIBLE,260,185,10,25,hwnd,NULL,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL);
    CreateWindow("STATIC","180",WS_CHILD | WS_VISIBLE,445,185,25,25,hwnd,NULL,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL);
    
    // Создание окна надписи текущего значения ScrollBar
    hwndStatic = CreateWindow("STATIC","00",WS_CHILD | WS_VISIBLE,353,186,30,25,hwnd,NULL,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),NULL);
    
    return TRUE;
}

void MainWindowOnHScroll(HWND,HWND hwndCtrl, UINT nCodeNotify, int nPos)
{
    char szT[4] = {NULL};
    
    if(hwndCtrl == hwndTrack && nCodeNotify == TB_ENDTRACK)
        nFreq = SendMessage(hwndTrack,TBM_GETPOS,0,0);

    if(hwndCtrl == hwndScroll)
    {
        switch(nCodeNotify)
        {
            case SB_LINERIGHT:
                sinfo.nPos++;
                if(sinfo.nPos > sinfo.nMax)
                    sinfo.nPos = sinfo.nMax;
                SetScrollInfo(hwndScroll,SB_CTL,&sinfo,TRUE);
                break;
            case SB_LINELEFT:
                sinfo.nPos--;
                if(sinfo.nPos < sinfo.nMin)
                    sinfo.nPos = sinfo.nMin;
                SetScrollInfo(hwndScroll,SB_CTL,&sinfo,TRUE);
                break;
            case SB_PAGERIGHT:
                sinfo.nPos+=18;
                if(sinfo.nPos > sinfo.nMax)
                    sinfo.nPos = sinfo.nMax;
                SetScrollInfo(hwndScroll,SB_CTL,&sinfo,TRUE);
                break;
            case SB_PAGELEFT:
                sinfo.nPos-=18;
                if(sinfo.nPos < sinfo.nMin)
                    sinfo.nPos = sinfo.nMin;
                SetScrollInfo(hwndScroll,SB_CTL,&sinfo,TRUE);
                break;
            case SB_THUMBTRACK:
                sinfo.nPos = nPos;
                if(sinfo.nPos < sinfo.nMin)
                    sinfo.nPos = sinfo.nMin;
                if(sinfo.nPos > sinfo.nMax)
                    sinfo.nPos = sinfo.nMax;
                SetScrollInfo(hwndScroll,SB_CTL,&sinfo,TRUE);
                break;    
        }
            wsprintf(szT,"%03d",sinfo.nPos);
            SetWindowText(hwndStatic,szT);
    }
}

HBRUSH MainWindowOnCtlColorStatic(HWND, HDC hdc,HWND hwndCtl, int)
{
    SetBkMode(hdc,TRANSPARENT);
    return GetStockBrush(LTGRAY_BRUSH);
}

void MainWindowOnDestroy(HWND)
{
    PostQuitMessage(0);
}

// Функции класса GraphWindow
LRESULT CALLBACK GraphWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        HANDLE_MSG(hwnd,WM_PAINT,GraphWindowOnPaint);
        default:
            return DefWindowProc(hwnd,msg,wParam,lParam);
    }
    
}

void GraphWindowOnPaint(HWND hwnd)
{
    
    
}


gui.h
Код

// Глобальные переменные
LPSTR lpszGraphClassName = "GraphWindow";
HWND hwndTrack;
HWND hwndScroll;
HWND hwndStatic;
SCROLLINFO sinfo;
short nFreq = 1;

// Прототипы функций класса MainWindow
LRESULT CALLBACK MainWindowWndProc(HWND,UINT,WPARAM,LPARAM);
BOOL MainWindowOnCreate(HWND,LPCREATESTRUCT);
void MainWindowOnHScroll(HWND,HWND,UINT,int);
HBRUSH MainWindowOnCtlColorStatic(HWND,HDC,HWND,int);
void MainWindowOnDestroy(HWND);

// Прототипы функций класса GraphWindow
LRESULT CALLBACK GraphWndProc(HWND,UINT,WPARAM,LPARAM);
void GraphWindowOnPaint(HWND);



Это программа выводит в белое окно график и с помощью контролов справа может регулировать его. График пока не рисовал но проблемы начались уже до него. Вообщем так несколько вопросов:
1) Почему при запуске программы не прорисовываются для контрола (они же окна со встроенными классами TRACKBAR_CLASS и "SCROLLBAR" соответственно), они появляются только в том случае если перемещать главное окно приложения. Хотя если в   GraphWndProc закоментить макрос HANDLE_MSG(hwnd,WM_PAINT,GraphWindowOnPaint), то все нормально (какое он к ним имеет отношение?). В этом макросе потом будет описан вывод графика в это белое окно.
2) Почему если перемещать каретку на ScrollBar до самого конца вправо, то визуально она доходит только до значения 163, т.е якобы это конец, хотя всего у меня 180 значений.

P.S: Заранее спасибо за Ваши ответы, мне они очень нужны т.к в книге Финогенов этого не описывает.

Это сообщение отредактировал(а) yngwie19 - 5.3.2009, 12:58
PM MAIL   Вверх
GremlinProg
Дата 6.3.2009, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(yngwie19 @  5.3.2009,  14:55 Найти цитируемый пост)
Почему при запуске программы не прорисовываются для контрола

потому что эти классы используют родительский девайс для рисования, т.е. используют CS_PARENTDC при регистрации
отсюда и зависимость

смотри внимательно на свой код:
Код

...
    switch(msg)
    {
        HANDLE_MSG(hwnd,WM_PAINT,GraphWindowOnPaint);
        default:
            return DefWindowProc(hwnd,msg,wParam,lParam);
    }
...
void GraphWindowOnPaint(HWND hwnd)
{
    
    
}

у тебя тут на WM_PAINT блокируется DefWindowProc, а в обработчике ни каких действий по выводу графики нет,
сделай хотя бы минимум:
Код

void GraphWindowOnPaint(HWND hwnd)
{
    PAINTSTRUCT ps;
    ::BeginPaint(hwnd,&ps);
    ::EndPaint(hwnd,&ps);
}

BeginPaint, на самом деле, много чего делает, в том числе, и уведомляет дочерние компоненты о перерисовке, если они были перекрыты, так что не стоит ее игнорировать, если нечего предложить взамен

Цитата(yngwie19 @  5.3.2009,  14:55 Найти цитируемый пост)
Почему если перемещать каретку на ScrollBar до самого конца вправо, то визуально она доходит только до значения 163, т.е якобы это конец, хотя всего у меня 180 значений.

тут ошибок нет, полоса прокрутки - оконный компонент в том плане, что его окно(ползунок) входит в область расчета, в отличии от трекбаров, поэтому, и параметр sinfo.nPage - не дополнение к sinfo.nMax, а его состаная часть
если хочешь чтобы скроллбар работал как трекбар, то сделай одно из двух:
первое:
Код

    sinfo.nMax = 180;
    sinfo.nPage = 1;

либо второе
Код

    sinfo.nPage = 18;
    sinfo.nMax = 180 + 18;

визуально, решения различаются, смотри сам какое нужно


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



GremlinProg, Спасибо тебе огромное ты очень мне помог )))).
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.

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


 




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


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

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