Форум программистов, компьютерный форум CyberForum.ru

Дочернее окно - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 28, средняя оценка - 4.68
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
18.08.2011, 00:53     Дочернее окно #1
Не могу найти как создается дочернее окно. Надо подготовить курсовик по WinApi. Я долго оттягивал, но делать - то надо. Что же, придется убить время на программирование для виндовс, может и пригодится. Итак, задача у меня для низкого старта, так что я буду в этой теме спрашивать по мере необходимости. На данном этапе мне нужно просто создать 2 дочерних окна. Вот пока есть сам скелет, на который будет натягиваться кожа.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <windows.h>
#include <tchar.h>
 
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
TCHAR WinName[] = _T("MainFrame");
int APIENTRY _tWinMain(HINSTANCE This, HINSTANCE Prev,
    LPTSTR cmd, int mode)
{
    HWND hWnd;     //Дескриптор главного окна программы
    MSG msg;       //Структура для хранения сообщения   
    WNDCLASS wc;   //Класс окна с дальнейшим его определением
 
    wc.hInstance        = This;
    wc.lpszClassName    = WinName;                              //Имя класса окна
    wc.lpfnWndProc      = WndProc;                              //Функция окна
    wc.style            = CS_HREDRAW |CS_VREDRAW;               //Стиль окна
    wc.hIcon            = LoadIcon (NULL, IDI_WINLOGO);         //Иконка по умолчанию
    wc.hCursor          = LoadCursor (NULL, IDC_ARROW);         //Курсор мыши
    wc.lpszMenuName     = NULL;                                 //Меню нету
    wc.cbClsExtra       = 0;                                    //Нет доролнительных данных класса
    wc.cbWndExtra       = 0;                                    //Нет дополнительных данных
    wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);             //Заполнение окна белым цветом
    //Регистрация класса окна
    RegisterClass(&wc);
        
    hWnd = CreateWindow(WinName,            //имя класса окна
        _T("Каркасс оконного приложения")//Заголовок окна
        WS_OVERLAPPEDWINDOW,                //стиль окна
        CW_USEDEFAULT,                      //x
        CW_USEDEFAULT,                      //y
        CW_USEDEFAULT,                      //Ширина (widht)
        CW_USEDEFAULT,                      //Высота (height)
        HWND_DESKTOP,                       //Дескриптор родительского окна
        NULL,                               //Нет меню
        This,                               //Дескриптор приложения
        NULL                                //Дполнительная информация
        );
    ShowWindow(hWnd, mode);                 //Показать окно
    //Цикл обработки сообщений
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);             //Функция транслирования кодов нажатой клавиши
        DispatchMessage(&msg);              //Посылает сообщение функции WndProc
    }
    return 0;
}
//Оконная процедура. Вызывается ОС-й и получает сообщения из очереди
//для данного приложения
LRESULT CALLBACK WndProc (HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch (Message)
    {
    case WM_DESTROY: 
        PostQuitMessage(0);
        break;
    default: return DefWindowProc(hWnd, Message, wParam, lParam);
    }
    return 0;
}
Как я понимаю надо объявить еще две переменные void* рядом и описать их?
C++
1
HWND hWnd, child_1, child_2;
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
bretba
 Аватар для bretba
63 / 58 / 5
Регистрация: 24.07.2011
Сообщений: 343
18.08.2011, 01:01     Дочернее окно #2
Дочернее окно создается так же как и основное с помощью функции createwindow

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HWND CreateWindowEx(
 
DWORD dwExStyle,       
 LPCTSTR lpClassName,   
 LPCTSTR lpWindowName,  
 DWORD dwStyle,         //  стиль окна
 int x,                
 int y,                 
 int nWidth,            
 int nHeight,           
 HWND hWndParent,      //  дескриптор родительского или окна владельца
 HMENU hMenu,           
 HINSTANCE hInstance,   
 LPVOID lpParam        
 
 );
Важные параметры для дочернего-это HWND hWndParent и DWORD dwStyle

HWND hWndParent-это ссылка на родительский дескриптор
DWORD dwStyle -стиль,который должен быть WS_CHILD
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
18.08.2011, 01:09  [ТС]     Дочернее окно #3
а что если сделать вот так?
C++
1
2
HWND hWndParent //как взять дескриптор родительского окна?
dwExStyle = WS_EX_MDICHILD
bretba
 Аватар для bretba
63 / 58 / 5
Регистрация: 24.07.2011
Сообщений: 343
18.08.2011, 01:48     Дочернее окно #4
Не понял вопроса?

Цитата Сообщение от alkagolik Посмотреть сообщение
HWND hWnd; //Дескриптор главного окна программы
вот вы сами пишете что это дескриптор главного окна
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
18.08.2011, 02:00  [ТС]     Дочернее окно #5
да да, то я сначала спросил, а потом подумал... впопыхах. вот так не работает
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
int APIENTRY _tWinMain(HINSTANCE This, HINSTANCE Prev,
    LPTSTR cmd, int mode)
{
    HWND hWnd, child_OM/*operation memory*/, child_GM/*global memory*/; //Дескрипторы окон
    MSG msg;       //Структура для хранения сообщения   
    WNDCLASS wc;   //Класс окна с дальнейшим его определением
 
    wc.hInstance        = This;
    wc.lpszClassName    = WinName;                              //Имя класса окна
    wc.lpfnWndProc      = WndProc;                              //Функция окна
    wc.style            = CS_HREDRAW |CS_VREDRAW;               //Стиль окна
    wc.hIcon            = LoadIcon (NULL, IDI_WINLOGO);         //Иконка по умолчанию
    wc.hCursor          = LoadCursor (NULL, IDC_ARROW);         //Курсор мыши
    wc.lpszMenuName     = NULL;                                 //Меню нету
    wc.cbClsExtra       = 0;                                    //Нет доролнительных данных класса
    wc.cbWndExtra       = 0;                                    //Нет дополнительных данных
    wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);             //Заполнение окна белым цветом
    //Регистрация класса окна
    RegisterClass(&wc);
        
    hWnd = CreateWindow(WinName,            //имя класса окна
        _T("Курсовая работа по системному программированию"),   //Заголовок окна
        WS_OVERLAPPEDWINDOW,                //стиль окна
        CW_USEDEFAULT,                      //x
        CW_USEDEFAULT,                      //y
        800,                                //Ширина (widht)
        600,                                //Высота (height)
        HWND_DESKTOP,                       //Дескриптор родительского окна
        NULL,                               //Нет меню
        This,                               //Дескриптор приложения
        NULL                                //Дполнительная информация
        );
 
    child_OM = CreateWindow(
        NULL,
        _T("график "),
        WS_CHILD,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        800,
        300,
        hWnd,
        NULL,
        This,
        NULL
        );
 
    ShowWindow(hWnd, mode);                     //Показать окно
    ShowWindow(child_OM, mode);                 //Показать окно
    //Цикл обработки сообщений
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);             //Функция транслирования кодов нажатой клавиши
        DispatchMessage(&msg);              //Посылает сообщение функции WndProc
    }
    return 0;
}
оговорюсь что WM_PAINT еще не добавлен.
stdcout
53 / 53 / 2
Регистрация: 06.04.2011
Сообщений: 210
18.08.2011, 09:12     Дочернее окно #6
alkagolik,
C
1
2
child_OM = CreateWindow(
                NULL,
Не знаю, как хорошо будет работать ваш код. У вас вместо имени класса для дочернего окна стоит NULL. Но мне кажется, что нужно зарегистрировать класс и для дочернего окна и передать в CreateWindow имя этого класса. И возможно для дочернего окна нужно будет написать отдельный обработчик.
bretba
 Аватар для bretba
63 / 58 / 5
Регистрация: 24.07.2011
Сообщений: 343
18.08.2011, 14:48     Дочернее окно #7
stdcout,да...нужно...ведь может быть мы хотим изменить иконку,курсор и многое другое для дочернего окна и самое главное это имя класса естественно...его нужно передавать в функцию createwindow
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
18.08.2011, 21:35  [ТС]     Дочернее окно #8
Ну вот я так переделал. Компилирует, но не запускает. ошибка с номером -3 (регистрация дочернего класса) что не так? MessageBos не поддерживает шрифтов рус\англ. Где в свойствах подпрваить?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <Windows.h>
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM, LPARAM);
 
 
int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    
    HWND hWnd;          //Дескриптор главного окна программы
    MSG msg;            //Структура для хранения сообщения   
    WNDCLASSEX wc;      //Класс главного окна программы
    
    char ClassPName[] = "ClassParent";
    wc.cbSize       = sizeof(wc);
    wc.style        = WS_OVERLAPPEDWINDOW | CS_HREDRAW | CS_HREDRAW;
    wc.lpfnWndProc  = WndProc;
    wc.cbClsExtra   = 0;
    wc.cbWndExtra   = 0;
    wc.hInstance    = hInstance;
    wc.hIcon        = LoadIcon(NULL, IDI_APPLICATION) ;
    wc.hCursor      = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName= (LPWSTR)ClassPName;
    wc.hIconSm      = LoadIcon (NULL, IDI_APPLICATION);
 
    if(!RegisterClassEx(&wc)){
        MessageBox(NULL,(LPCWSTR) "Can't register class parrent",
            (LPCWSTR) "Error", MB_OK);
        return -1;
    }
 
    hWnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        (LPWSTR)ClassPName,
        (LPWSTR)"Kursovaya Rabota",
        WS_OVERLAPPEDWINDOW,
        900, 600, 300, 300,
        NULL, NULL,
        hInstance, NULL);
    if(!hWnd){
        MessageBox(NULL,(LPCWSTR) "Can't create parent window",
            (LPCWSTR) "Error", MB_OK);
        return -2;
    }
        
    HWND hChldOM, hChldGM;          //Дескриптор главного окна программы
    WNDCLASSEX wchcl;       //Класс главного окна программы
    
    char ClassChName[]      = "ClassParent";
    wchcl.cbSize            = sizeof(wchcl);
    wchcl.style             = WS_OVERLAPPEDWINDOW|CS_HREDRAW | CS_HREDRAW;
    wchcl.lpfnWndProc       = ChildProc;
    wchcl.cbClsExtra        = 0;
    wchcl.cbWndExtra        = 0;
    wchcl.hInstance         = hInstance;
    wchcl.hIcon             = LoadIcon(NULL, IDI_APPLICATION) ;
    wchcl.hCursor           = LoadCursor(NULL, IDC_ARROW);
    wchcl.hbrBackground     = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wchcl.lpszMenuName      = NULL;
    wchcl.lpszClassName     = (LPWSTR)ClassChName;
    wchcl.hIconSm           = LoadIcon (NULL, IDI_APPLICATION);
 
    if(!RegisterClassEx(&wchcl)){
        MessageBox(NULL,(LPCWSTR) "Can't register child class",
            (LPCWSTR) "Error", MB_OK);
        return -3;
    }
 
    hChldOM = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        (LPWSTR)ClassChName,
        (LPWSTR)"Graphik operativnoy pamyaty",
        WS_CHILD,
        900, 600, 300, 150,
        hWnd, NULL,
        hInstance, NULL);
    if(!hChldOM){
        MessageBox(NULL,(LPCWSTR) "Can't create child window",
            (LPCWSTR) "Error", MB_OK);
        return -4;
    }
    
    hChldGM = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        (LPWSTR)ClassChName,
        (LPWSTR)"Graphik phizicheskoi pamyzti",
        WS_CHILD,
        900, 300, 300, 150,
        hWnd, NULL,
        hInstance, NULL);
    if(!hChldGM){
        MessageBox(NULL,(LPCWSTR) "Can't create child window",
            (LPCWSTR) "Error", MB_OK);
        return -5;
    }
    
    ShowWindow(hWnd, nCmdShow);
    ShowWindow(hChldOM, nCmdShow);
    ShowWindow(hChldGM, nCmdShow);
 
    while(GetMessage(&msg, NULL, 0, 0)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
 
    return 0;
}
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
        switch (uMsg)
        {
        case WM_DESTROY: 
                PostQuitMessage(0);
                break;
        default: return DefWindowProc(hWnd, uMsg, wParam, lParam);
        }
        return 0;
}
LRESULT CALLBACK ChildProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_DESTROY )
    {
        return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Добавлено через 19 минут
Подправил строку 52, запустилось. но кракозябры все равно остались
stdcout
53 / 53 / 2
Регистрация: 06.04.2011
Сообщений: 210
18.08.2011, 21:48     Дочернее окно #9
alkagolik, Почитай лучше хорошую литературу, поищи темы в разделе WinAPI. Так для тебя и быстрее будет и понятнее что да как.
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
18.08.2011, 22:16  [ТС]     Дочернее окно #10
Цитата Сообщение от stdcout Посмотреть сообщение
alkagolik, Почитай лучше хорошую литературу, поищи темы в разделе WinAPI. Так для тебя и быстрее будет и понятнее что да как.
Нету ни желания ни времени. Работать в Виндовс и так напряжение, а кодить для говноОС напряжение вдвойне. Уж и так читаю читаю и понять все не могу зачем в ядре столько уровней, и зачем такой ГИГАНТСКИЙ набор API функций.... и еще много к чему придраться есть Но это все оффтоп.
jonson
18.08.2011, 22:30
  #11

Не по теме:

Цитата Сообщение от alkagolik Посмотреть сообщение
Работать в Виндовс и так напряжение, а кодить для говноОС напряжение вдвойне.
Странный вывод... Врятли есть ОС где вам придраться будет не к чему

alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
18.08.2011, 22:35  [ТС]     Дочернее окно #12
jonson, спокойно товарищ, не вывод, а субъективное восприятие + привычки + раздраженность от перемены рабочей среды. Эмоционально конечно, но доля истины есть... а по теме? Я читаю Литвиненко "Программирование на С win32api" в очень плохом качестве, но содержание как раз то что надо, есть в хорошем?
jonson
 Аватар для jonson
231 / 204 / 61
Регистрация: 18.03.2010
Сообщений: 749
18.08.2011, 23:05     Дочернее окно #13
я так понял вам нужен многооконный интерфейс средствами WinAPI.
вот тут или тут гляньте, по моему достаточно ясно.
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
19.08.2011, 03:05  [ТС]     Дочернее окно #14
Ну в принципе есть окошко, с двумя дочками, кодировки в проекте выстроил, только не пойму как вторую дочку привязать к родителю левым нижним углом к левому нижнему углу родителя, а так процесс идет, не стоит на месте. Этот вопрос специфический, сходу не нагуглишь. подскажите кто знает. код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <Windows.h>
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM, LPARAM);
 
 
int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    
    HWND hWnd;          //Дескриптор главного окна программы
    MSG msg;            //Структура для хранения сообщения   
    WNDCLASSEX wc;      //Класс главного окна программы
    
    char ClassPName[] = "ClassParent";
    wc.cbSize       = sizeof(wc);
    wc.style        = CS_HREDRAW | CS_HREDRAW;
    wc.lpfnWndProc  = WndProc;
    wc.cbClsExtra   = 0;
    wc.cbWndExtra   = 0;
    wc.hInstance    = hInstance;
    wc.hIcon        = LoadIcon(NULL, IDI_APPLICATION) ;
    wc.hCursor      = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName= ClassPName;
    wc.hIconSm      = LoadIcon (NULL, IDI_APPLICATION);
 
    if(!RegisterClassEx(&wc)){
        MessageBox(NULL, "не удается зарегистрировать родительский класс",
            "Ошибка!", MB_OK);
        return -1;
    }
 
    hWnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        ClassPName,
        "Курсовая работа",
        WS_OVERLAPPEDWINDOW,
        250, 250, 800, 600,
        NULL, NULL,
        hInstance, NULL);
    if(!hWnd){
        MessageBox(NULL,"не удается создать родительское окно",
            "Ошибка!", MB_OK);
        return -2;
    }
        
    HWND hChldOM, hChldGM;          
    WNDCLASSEX wchcl;
    
    char ClassChName[]      = "ClassChild";
    wchcl.cbSize            = sizeof(wchcl);
    wchcl.style             = CS_HREDRAW | CS_HREDRAW;
    wchcl.lpfnWndProc       = ChildProc;
    wchcl.cbClsExtra        = 0;
    wchcl.cbWndExtra        = 0;
    wchcl.hInstance         = hInstance;
    wchcl.hIcon             = LoadIcon(NULL, IDI_APPLICATION) ;
    wchcl.hCursor           = LoadCursor(NULL, IDC_ARROW);
    wchcl.hbrBackground     = (HBRUSH)GetStockObject(GRAY_BRUSH);
    wchcl.lpszMenuName      = NULL;
    wchcl.lpszClassName     = ClassChName;
    wchcl.hIconSm           = LoadIcon (NULL, IDI_APPLICATION);
 
    if(!RegisterClassEx(&wchcl)){
        MessageBox(NULL, "не удается зарегистрировать дочерний класс",
            "Ошибка!", MB_OK);
        return -3;
    }
 
    hChldOM = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        ClassChName,
        "График оперативной памяти",
        WS_CHILD|WS_BORDER|WS_VISIBLE,
        CW_USEDEFAULT, CW_USEDEFAULT, 800, 300,
        hWnd, NULL,
        hInstance, NULL);
    if(!hChldOM){
        MessageBox(NULL,"Не удается создать дочернее окно",
            "Ошибка!", MB_OK);
        return -4;
    }
    
    hChldGM = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        ClassChName,
        "График глобальной памяти",
        WS_CHILD|WS_BORDER|WS_VISIBLE,
        CW_USEDEFAULT, 550, 800, 300,
        hWnd, NULL,
        hInstance, NULL);
    if(!hChldGM){
        MessageBox(NULL,"не удается создать дочернее окно",
            "Ошибка", MB_OK);
        return -5;
    }
    
    ShowWindow(hWnd, nCmdShow);
    ShowWindow(hChldOM, nCmdShow);
    ShowWindow(hChldGM, nCmdShow);
    
    while(GetMessage(&msg, NULL, 0, 0)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
 
    return 0;
}
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_CREATE:
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default: return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}
LRESULT CALLBACK ChildProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_DESTROY )
    {
        return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Добавлено через 8 минут
jonson, спасибо, а то я вот отсюда читал, прямо жуть, но лучше не нашел... знал бы что искать. Но я так и не понял толком что такое MDI. Это фреймы в родителе? это всплывающие диалоги? в смысле их природа какая?

Добавлено через 3 часа 49 минут
В общем проблема такого характера. При попытке вызвать
C++
1
2
3
4
5
...
case WM_SIZE:
    GetClientRect(hWnd, &rcClient);
    MoveWindow(hChldOM, ...);
...
Естественно необъявленный идентификатор hChldOM
При попытке создать дочки в процедуре WinProc не хватает параметра hInstance, хотел его хранить в промежуточной переменной. но он вообще не инициализирован. Как быть? что делать?
stdcout
53 / 53 / 2
Регистрация: 06.04.2011
Сообщений: 210
19.08.2011, 08:35     Дочернее окно #15
alkagolik, при обработке сообщения WM_CREATE параметр lParam фактически является указателем на структуру типа CREATESTRUCT. В этой структуре есть поле hInstance, которое ты задаёшь предпоследним параметром в CreateWindowEx. Создай статическую переменную и сохрани в неё значение hInstance. Примерно так:
C
1
2
3
4
5
6
7
8
9
10
static HINSTANCE hInstance;
/*  */
switch (uMsg)
{
    case WM_CREATE:
        hInstance = ((CREATESTRUCT *) lParam)->hInstance;
        return 0;
    /*  */
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
19.08.2011, 20:24  [ТС]     Дочернее окно #16
Ну все пока идет гут. Подскажите пожалуйста почему я рисую одно дочернее окно. а перерисовывается сразу два? как тут подпилить?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <Windows.h>
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam);
 
char ClassChName[]  = "ClassChild";
char ClassPName[] = "ClassParent";
 
 
int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    
    HWND hWnd;          //Дескриптор главного окна программы
    MSG msg;            //Структура для хранения сообщения   
    WNDCLASSEX wc;      //Класс главного окна программы
    
    
    wc.cbSize       = sizeof(wc);
    wc.style        = CS_OWNDC;
    wc.lpfnWndProc  = WndProc;
    wc.cbClsExtra   = 0;
    wc.cbWndExtra   = 0;
    wc.hInstance    = hInstance;
    wc.hIcon        = LoadIcon(NULL, IDI_APPLICATION) ;
    wc.hCursor      = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName= ClassPName;
    wc.hIconSm      = LoadIcon (NULL, IDI_APPLICATION);
 
    if(!RegisterClassEx(&wc)){
        MessageBox(NULL, "не удается зарегистрировать родительский класс",
            "Ошибка!", MB_OK);
        return -1;
    }
 
    hWnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        ClassPName,
        "Курсовая работа",
        WS_OVERLAPPEDWINDOW,
        //(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | \
        WS_MAXIMIZEBOX) &~(WS_THICKFRAME),
        250, 250, 600, 480,
        NULL, NULL,
        hInstance, NULL);
    if(!hWnd){
        MessageBox(NULL,"не удается создать родительское окно",
            "Ошибка!", MB_OK);
        return -2;
    }
    
    ShowWindow(hWnd, nCmdShow);
    while(GetMessage(&msg, NULL, 0, 0)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
 
    return 0;
}
 
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    RECT rect;
    PAINTSTRUCT ps;
    HDC hDC;
    int xGM, yGM, xOM, yOM;
    HWND hChldOM, hChldGM;
    static HINSTANCE hInst;
 
 
    switch (uMsg)
    {
        case WM_CREATE:
            hInst = ((CREATESTRUCT*)lParam)->hInstance;
                        
            WNDCLASSEX wchcl;
            wchcl.cbSize            = sizeof(wchcl);
            wchcl.style             = CS_HREDRAW | CS_HREDRAW;
            wchcl.lpfnWndProc       = ChildProc;
            wchcl.cbClsExtra        = 0;
            wchcl.cbWndExtra        = 0;
            wchcl.hInstance         = hInst;
            wchcl.hIcon             = LoadIcon(NULL, IDI_APPLICATION) ;
            wchcl.hCursor           = LoadCursor(NULL, IDC_ARROW);
            wchcl.hbrBackground     = (HBRUSH)GetStockObject(WHITE_BRUSH);
            wchcl.lpszMenuName      = NULL;
            wchcl.lpszClassName     = ClassChName;
            wchcl.hIconSm           = LoadIcon (NULL, IDI_APPLICATION);
 
            if(!RegisterClassEx(&wchcl)){
                MessageBox(NULL, "не удается зарегистрировать дочерний класс",
                    "Ошибка!", MB_OK);
                return -3;
            }
            
            hChldOM = CreateWindowEx(WS_EX_CLIENTEDGE, ClassChName,
                "График оперативной памяти", WS_CHILD|WS_BORDER|WS_VISIBLE, 
                0, 0, 600, 220,
                hWnd, NULL, hInst, NULL);
 
            if(!hChldOM){
                MessageBox(NULL,"Не удается создать дочернее окно",
                    "Ошибка!", MB_OK);
                return -4;
            }
 
            hChldGM = CreateWindowEx(WS_EX_CLIENTEDGE, ClassChName,
                "График глобальной памяти", WS_CHILD|WS_BORDER|WS_VISIBLE,
                0, 220, ((CREATESTRUCT*)lParam)->cx, (((CREATESTRUCT*)lParam)->cy)/2,
                hWnd, NULL, hInst, NULL);
            if(!hChldGM){
                MessageBox(NULL,"не удается создать дочернее окно",
                    "Ошибка", MB_OK);
                return -5;
            }
 
            if(!ShowWindow(hChldOM, SW_SHOW)){
                MessageBox(NULL,"!ShowWindow(hChldOM, SW_SHOWNORMAL)",
                    "Ошибка", MB_OK);
                return -6;
            }
            if(!ShowWindow(hChldGM, SW_SHOW)){
                MessageBox(NULL,"!ShowWindow(hChldOM, SW_SHOWNORMAL)",
                    "Ошибка", MB_OK);
                return -7;
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default: return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}
 
LRESULT CALLBACK ChildProc(HWND hChldGM, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    RECT rect;
    HDC hDC;
    PAINTSTRUCT ps;
    int x, y;
    static HPEN hpen;
    if (uMsg == WM_DESTROY )
    {
        return 0;
    }
    switch(uMsg)
    {
    case WM_PAINT:
        hDC = BeginPaint(hChldGM, &ps);
        GetClientRect(hChldGM, &rect);
        x = rect.left + 5;
        y = rect.bottom + 5;
        SelectObject(hDC, hpen);
        MoveToEx(hDC, x, y, NULL);
        LineTo(hDC, x, rect.top -5);
        EndPaint(hChldGM, &ps);
 
    }
    return DefWindowProc(hChldGM, uMsg, wParam, lParam);;
}
Добавлено через 1 час 6 минут
Я конечно понимаю что можно реализовать отдельный класс и отдельную процедуру для каждой дочки. Но надо ли это делать? Или именно так и надо сделать?
stdcout
53 / 53 / 2
Регистрация: 06.04.2011
Сообщений: 210
19.08.2011, 21:44     Дочернее окно #17
alkagolik, основная суть класса в том, чтобы предоставить всем окнам данного класса определённую процедуру (на которую указывает член lpfnWndProc структуры WNDCLASSEX), ну ещё там иконка, курсор и т. д. Если для всех дочерних окон необходимо примерно одинаковое поведение, то естественно, что достаточно одного класса.
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
20.08.2011, 01:28  [ТС]     Дочернее окно #18
Цитата Сообщение от stdcout Посмотреть сообщение
Если для всех дочерних окон необходимо примерно одинаковое поведение
Поведение действительно необходимо одинаковое, даже не примерно а полностью, только для разных дочек с разными данными. И все таки как в общей процедуре выловить отдельное окно? Или все таки правильно слепить разные классы и процедуры?

Добавлено через 2 часа 33 минуты
В общем я пока описал отдельные класс и процедуру для каждой дочки, не знаю правильно или нет, но пока пусть будет так. Установил таймеры. Надо чтобы по срабатывании таймера рисовался график в дочке. Пока решение вижу так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
bool check = false //глобальная переменная
....
LRESULT CALLBACK ChildProcOM(HWND hChldOM, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
      ...
      case WM_TIMER:
            check = true;
      case WM_PAINT:
            if (check){
                 check = false;
                 ....
            }
}
В принципе конструкция должна работать, сейчас напишу проверю. Правильно такое решение или есть иное, которое принципиально?

Добавлено через 13 минут
конструкция работает, какая функция считывает информацию об оперативной памяти системы?
jonson
 Аватар для jonson
231 / 204 / 61
Регистрация: 18.03.2010
Сообщений: 749
20.08.2011, 02:17     Дочернее окно #19
Цитата Сообщение от alkagolik Посмотреть сообщение
какая функция считывает информацию об оперативной памяти системы?
тыц сюда
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.08.2011, 03:46     Дочернее окно
Еще ссылки по теме:

Окно ресурсов C++
C++ Окно Ханна
C++ Создать окно с кнопкой, закрывающей это окно

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
20.08.2011, 03:46  [ТС]     Дочернее окно #20
jonson, спасибо, но это был скорее риторический вопрос. msdn how to get RAM. Но по сути вопроса, Не работает рисование графика с таймером LRESULT CALLBACK ChildProcOM строка 165
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
#include <Windows.h>
 
#define TINER_CHILDOM 1
#define TINER_CHILDGM 2
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProcGM(HWND hChldGM, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ChildProcOM(HWND hChldOM, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
char const ClassChNameOM[]  = "ClassChildOM";
char const ClassChNameGM[]  = "ClassChildGM";
char const ClassPName[]     = "ClassParent";
 
static HPEN hpen1 = CreatePen(PS_SOLID, 2, RGB(128, 128, 128));
static HPEN hpen2 = CreatePen(PS_SOLID, 1, RGB(192, 192, 192));
 
static int xOM = 0, yOM = 0, xGM = 0, yGM = 0;
bool checkOM = false, checkGM = false;
 
int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    
    HWND hWnd;          //Дескриптор главного окна программы
    MSG msg;            //Структура для хранения сообщения   
    WNDCLASSEX wc;      //Класс главного окна программы
    
    
    wc.cbSize       = sizeof(wc);
    wc.style        = CS_OWNDC;
    wc.lpfnWndProc  = WndProc;
    wc.cbClsExtra   = 0;
    wc.cbWndExtra   = 0;
    wc.hInstance    = hInstance;
    wc.hIcon        = LoadIcon(NULL, IDI_APPLICATION) ;
    wc.hCursor      = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName= ClassPName;
    wc.hIconSm      = LoadIcon (NULL, IDI_APPLICATION);
 
    if(!RegisterClassEx(&wc)){
        MessageBox(NULL, "не удается зарегистрировать родительский класс",
            "Ошибка!", MB_OK);
        return -1;
    }
 
    hWnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        ClassPName,
        "Курсовая работа",
        //WS_OVERLAPPEDWINDOW,
        (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | 
        WS_MAXIMIZEBOX) &~(WS_THICKFRAME),
        250, 250, 600, 480,
        NULL, NULL,
        hInstance, NULL);
    if(!hWnd){
        MessageBox(NULL,"не удается создать родительское окно",
            "Ошибка!", MB_OK);
        return -2;
    }
    
    ShowWindow(hWnd, nCmdShow);
    while(GetMessage(&msg, NULL, 0, 0)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
 
    return 0;
}
 
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    HWND hChldOM, hChldGM;
    static HINSTANCE hInst;
 
 
    switch (uMsg)
    {
        case WM_CREATE:
            hInst = ((CREATESTRUCT*)lParam)->hInstance;
                        
            WNDCLASSEX wchclOM;
            wchclOM.cbSize          = sizeof(wchclOM);
            wchclOM.style               = CS_HREDRAW | CS_HREDRAW;
            wchclOM.lpfnWndProc     = ChildProcOM;
            wchclOM.cbClsExtra      = 0;
            wchclOM.cbWndExtra      = 0;
            wchclOM.hInstance           = hInst;
            wchclOM.hIcon               = LoadIcon(NULL, IDI_APPLICATION) ;
            wchclOM.hCursor         = LoadCursor(NULL, IDC_ARROW);
            wchclOM.hbrBackground       = (HBRUSH)GetStockObject(WHITE_BRUSH);
            wchclOM.lpszMenuName        = NULL;
            wchclOM.lpszClassName       = ClassChNameOM;
            wchclOM.hIconSm         = LoadIcon (NULL, IDI_APPLICATION);
 
            if(!RegisterClassEx(&wchclOM)){
                MessageBox(NULL, "не удается зарегистрировать дочерний класс",
                    "Ошибка!", MB_OK);
                return -3;
            }
            
            WNDCLASSEX wchclGM;
            wchclGM.cbSize          = sizeof(wchclGM);
            wchclGM.style               = CS_HREDRAW | CS_HREDRAW;
            wchclGM.lpfnWndProc     = ChildProcGM;
            wchclGM.cbClsExtra      = 0;
            wchclGM.cbWndExtra      = 0;
            wchclGM.hInstance           = hInst;
            wchclGM.hIcon               = LoadIcon(NULL, IDI_APPLICATION) ;
            wchclGM.hCursor         = LoadCursor(NULL, IDC_ARROW);
            wchclGM.hbrBackground       = (HBRUSH)GetStockObject(WHITE_BRUSH);
            wchclGM.lpszMenuName        = NULL;
            wchclGM.lpszClassName       = ClassChNameGM;
            wchclGM.hIconSm         = LoadIcon (NULL, IDI_APPLICATION);
 
            if(!RegisterClassEx(&wchclGM)){
                MessageBox(NULL, "не удается зарегистрировать дочерний класс",
                    "Ошибка!", MB_OK);
                return -4;
            }
 
            hChldOM = CreateWindowEx(WS_EX_CLIENTEDGE, ClassChNameOM,
                "График оперативной памяти", WS_CHILD|WS_BORDER|WS_VISIBLE, 
                0, 0, 600, 220,
                hWnd, NULL, hInst, NULL);
 
            if(!hChldOM){
                MessageBox(NULL,"Не удается создать дочернее окно",
                    "Ошибка!", MB_OK);
                return -5;
            }
 
            hChldGM = CreateWindowEx(WS_EX_CLIENTEDGE, ClassChNameGM,
                "График глобальной памяти", WS_CHILD|WS_BORDER|WS_VISIBLE,
                0, 220, 600, 220,
                hWnd, NULL, hInst, NULL);
            if(!hChldGM){
                MessageBox(NULL,"не удается создать дочернее окно",
                    "Ошибка", MB_OK);
                return -6;
            }
 
            if(!ShowWindow(hChldOM, SW_SHOW)){
                MessageBox(NULL,"!ShowWindow(hChldOM, SW_SHOWNORMAL)",
                    "Ошибка", MB_OK);
                return -7;
            }
            if(!ShowWindow(hChldGM, SW_SHOW)){
                MessageBox(NULL,"!ShowWindow(hChldOM, SW_SHOWNORMAL)",
                    "Ошибка", MB_OK);
                return -8;
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default: return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}
 
LRESULT CALLBACK ChildProcOM(HWND hChldOM, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    RECT rect;
    HDC hDC;
    PAINTSTRUCT ps;
    static int x, y, tmp, ymax, ymin;
    GetClientRect(hChldOM, &rect);
 
    ymax = rect.bottom - 10;
    ymin = rect.top +5;
    
    switch(uMsg)
    {
    case WM_CREATE:
        SetTimer(hChldOM, TINER_CHILDOM, 1000, NULL);
        break;
    case WM_TIMER:
        checkOM = true;
        break;
    case WM_PAINT:
        hDC = BeginPaint(hChldOM, &ps);
        GetClientRect(hChldOM, &rect);
        //отрисовка осей координат
        x = rect.left + 10;
        y = rect.bottom - 10;
        SelectObject(hDC, hpen1);
        MoveToEx(hDC, x, y, NULL);
        LineTo(hDC, x, rect.top +5);
        MoveToEx(hDC, x, y, NULL);
        LineTo(hDC, rect.right - 15, y);
        MoveToEx(hDC, x, y, NULL);
        tmp = (y - rect.top + 5)/4;
        MoveToEx(hDC, x, y - tmp, NULL);
        SelectObject(hDC, hpen2);
        LineTo(hDC, rect.right - 15, y - tmp);
        MoveToEx(hDC, x, y - 2 * tmp, NULL);
        LineTo(hDC, rect.right - 15, y - 2 * tmp);
        MoveToEx(hDC, x, y - 3 * tmp, NULL);
        LineTo(hDC, rect.right - 15, y - 3 * tmp);
        //вывод текста
        rect.left = rect.left + 15;
        DrawText(hDC, "Оперативная память", -1, &rect, DT_LEFT | DT_TOP);
        GetClientRect(hChldOM, &rect);
        if (checkOM){
            checkOM = false;
            if (xOM <= rect.left + 10) xOM = rect.right;
            --xOM;
            MEMORYSTATUSEX statex;
            statex.dwLength = sizeof(statex);
            GlobalMemoryStatusEx(&statex);
            yOM = ymax - (ymax - ymin)/(statex.ullTotalPhys/statex.ullAvailPhys);
            SetPixel(hDC, xOM, yOM, RGB(255, 0, 0));
        }
        
        EndPaint(hChldOM, &ps);
        break;
    case WM_DESTROY:
        DeleteObject(hpen1);
        DeleteObject(hpen2);
        KillTimer(hChldOM, TINER_CHILDOM);
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hChldOM, uMsg, wParam, lParam);;
}
 
LRESULT CALLBACK ChildProcGM(HWND hChldGM, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    RECT rect;
    HDC hDC;
    PAINTSTRUCT ps;
    int x, y, tmp;
    
    switch(uMsg)
    {
    case WM_PAINT:
        hDC = BeginPaint(hChldGM, &ps);
        GetClientRect(hChldGM, &rect);
        //отрисовка осей координат
        x = rect.left + 10;
        y = rect.bottom - 10;
        SelectObject(hDC, hpen1);
        MoveToEx(hDC, x, y, NULL);
        LineTo(hDC, x, rect.top +5);
        MoveToEx(hDC, x, y, NULL);
        LineTo(hDC, rect.right - 15, y);
        MoveToEx(hDC, x, y, NULL);
        tmp = (y - rect.top + 5)/4;
        MoveToEx(hDC, x, y - tmp, NULL);
        SelectObject(hDC, hpen2);
        LineTo(hDC, rect.right - 15, y - tmp);
        MoveToEx(hDC, x, y - 2 * tmp, NULL);
        LineTo(hDC, rect.right - 15, y - 2 * tmp);
        MoveToEx(hDC, x, y - 3 * tmp, NULL);
        LineTo(hDC, rect.right - 15, y - 3 * tmp);
        //вывод текста
        rect.left = rect.left + 15;
        DrawText(hDC, "Свободная память на диске", -1, &rect, DT_LEFT | DT_TOP);
        GetClientRect(hChldGM, &rect);
        EndPaint(hChldGM, &ps);
        break;
    case WM_DESTROY:
        DeleteObject(hpen1);
        DeleteObject(hpen2);
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hChldGM, uMsg, wParam, lParam);;
}
Добавлено через 1 час 13 минут
сейчас обратил внимание что первый пиксел рисуется, а дальше нет
Yandex
Объявления
20.08.2011, 03:46     Дочернее окно
Ответ Создать тему
Опции темы

Текущее время: 21:21. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru