Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202

Обработчик событий внутри класса создания окна

17.05.2015, 23:33. Показов 3450. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Хочу сделать класс для создания окна (в проекте хочу использовать несколько окон и чтобы не писать для каждого окна отдельный обработчик, хотелось бы как то стандартизировать класс создания окна) - его цель состоит в том, чтобы просто создавать окно + свой индивидуальный обработчик, как бы и окно и обработчик будут инкапсулированы в одном классе, проблема в том что я сделал что задумал, но когда начинаю использовать внутри классовые переменные в обработчике получаю краш окна:
Сам класс:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class WindowCreate
{
 
public:
    WindowCreate(char* WindowClassName, char* WIndowName, WndType type, HWND ParentHWND);
 
    bool WindowRegisterNewClass(char* WindowClassName);
    bool InitialWindow(char* WIndowName, WndType type, HWND ParentHWND);
 
    static long __stdcall ButtonProc1(HWND, UINT, WPARAM, LPARAM);
    long __stdcall ButtonProc(HWND, UINT, WPARAM, LPARAM);
 
        int test = 0;
 
};
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
long __stdcall WindowCreate::ButtonProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
 
    switch (message)
    {
 
    case WM_LBUTTONDOWN:
 
                        printf("%d", test);//выдает нереальное значение, как будто я вывожу мусор(пустое место в памяти)
 
            break;
    }
 
    return DefWindowProcA(hWnd, message, wParam, lParam);
}
 
long __stdcall WindowCreate::ButtonProc1(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
 
    WindowCreate* pButton = (WindowCreate*) GetWindowLongA(hWnd, GWLP_USERDATA);
 
    if (pButton != NULL)
    {
        return pButton->ButtonProc(hWnd, message, wParam, lParam);
    }
 
    return DefWindowProcA(hWnd, message, wParam, lParam);
}
Может кто знает другой путь??? Я с радостью приму
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.05.2015, 23:33
Ответы с готовыми решениями:

Обработчик событий нажатия кнопок мыши внутри цикла
Товарищи, подскажите. Уже весь мозг сломал. Проблема в следующем: я использую модуль graphABC, который с помощью цикла (for, repeat,...

Обработчик событий нажатия кнопок мыши внутри цикла. Не работает
Товарищи, подскажите. Уже весь мозг сломал. Проблема в следующем: я использую модуль graphABC, который с помощью цикла (for, repeat,...

Обработчик событий у динамического объекта класса
Есть класс, динамически создающий PictureBox. class MyClass { public PictureBox pb; public MyClass() ...

18
46 / 31 / 12
Регистрация: 21.04.2015
Сообщений: 82
18.05.2015, 06:56
Возможно, вы уничтожаете объект WindowCreate раньше, чем разрушается окно.
Проект, который можно скомпилировать, в студию.
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
18.05.2015, 07:51
Цитата Сообщение от ДЕСАНТУРА Посмотреть сообщение
long __stdcall ButtonProc(HWND, UINT, WPARAM, LPARAM);
Тут уже можно virtual, вызываешь функцию сам ведь, да ещё из указателя на объект. У Фень Юаня, в книге "Программирование графики для Windows" этот приём реализован успешно.
Цитата Сообщение от ДЕСАНТУРА Посмотреть сообщение
когда начинаю использовать внутри классовые переменные в обработчике получаю краш окна:
Правильно. Для того чтобы использовать "внутри классовые переменные" обработчик должен быть thiscall, т.е. сноси __stdcall из прокомментированной мной функции.
1
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202
18.05.2015, 10:48  [ТС]
Цитата Сообщение от Enno Посмотреть сообщение
Тут уже можно virtual, вызываешь функцию сам ведь, да ещё из указателя на объект. У Фень Юаня, в книге "Программирование графики для Windows" этот приём реализован успешно.

Правильно. Для того чтобы использовать "внутри классовые переменные" обработчик должен быть thiscall, т.е. сноси __stdcall из прокомментированной мной функции.
__thiscall не прокатило - тоже самое - переменная выдает нереальное значение, есть еще варианты?

Добавлено через 1 минуту
Цитата Сообщение от zenden2k Посмотреть сообщение
Возможно, вы уничтожаете объект WindowCreate раньше, чем разрушается окно.
Проект, который можно скомпилировать, в студию.
исключено
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
18.05.2015, 11:59
Цитата Сообщение от ДЕСАНТУРА Посмотреть сообщение
__thiscall не прокатило - тоже самое
Вместо __stdcall ничего не пиши.
Микроликбез:
int test = 0; - где это лежит значение, по какому адресу тянуться за данными? Подскажет адрес объекта! Откуда у функции адрес объекта? Если это stdcall или cdecl, то ниоткуда, хотя имя это видимо внутри функции. Функции с соглашением о вызове thiscall получают адрес объекта. Функции класса по умолчанию всегда thiscall, потому и могут оперировать переменными класса.
Вот тебе чисто для проверки:
Перед тем как зайти в ButtonProc проверь значение pButton (адрес там будет объекта), а как только зайдёшь, то сравни его со значением this (указатель на объект из которого вызвана функция). Если разные - функция не thiscall.
1
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202
18.05.2015, 13:06  [ТС]
Цитата Сообщение от Enno Посмотреть сообщение
Вместо __stdcall ничего не пиши.
Микроликбез:
int test = 0; - где это лежит значение, по какому адресу тянуться за данными? Подскажет адрес объекта! Откуда у функции адрес объекта? Если это stdcall или cdecl, то ниоткуда, хотя имя это видимо внутри функции. Функции с соглашением о вызове thiscall получают адрес объекта. Функции класса по умолчанию всегда thiscall, потому и могут оперировать переменными класса.
Вот тебе чисто для проверки:
Перед тем как зайти в ButtonProc проверь значение pButton (адрес там будет объекта), а как только зайдёшь, то сравни его со значением this (указатель на объект из которого вызвана функция). Если разные - функция не thiscall.
Это все я пробовал давно, это не катит тоже, я понял в чем дело, вызывается обработчик временно созданного экземпляра класса, а не тот который внутри данного объекта класса, а так как я не инициализировал временный класс и он абстрактен полностью, вот мне и выдает значение переменных как "мусор", то есть я обращаюсь к пустой памяти, походу никак тут нельзя нечего сделать и придется использовать для каждого окна свой обработчик.

Добавлено через 4 минуты
мне нужно как - то передать указатель на класс, в статическую функцию обработчика, а так как она "статик" - это сделать не реально, по крайней мере с моими знаниями.
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
18.05.2015, 14:10
ДЕСАНТУРА,
вот кусок кода от Фень Юаня:
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
class KWindow
{
    virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
    static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
/*
...
*/
};
 
LRESULT KWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch( uMsg )
    {
        case WM_KEYDOWN:
            OnKeyDown(wParam, lParam);
            return 0;
 
        case WM_PAINT:
        {
            PAINTSTRUCT ps; 
                
            BeginPaint(m_hWnd, &ps);
            OnDraw(ps.hdc);
            EndPaint(m_hWnd, &ps);
        }
        return 0;
 
        case WM_PALETTEISCHANGING: // should not happen
            MessageBox(NULL, _T("Hello"), _T("Hi"), MB_OK);
            return 0;
 
        case WM_PALETTECHANGED:
            return OnPaletteChanged(hWnd, wParam);
 
        case WM_QUERYNEWPALETTE:
            return OnQueryNewPalette();
 
        case WM_DESTROY:
            if ( m_bMainWindow )
                PostQuitMessage(0); // main window only
            return 0;
    }
 
   return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 
 
// Generic window procedure passed to WIN32 API, dispatches to KWindow::WndProc
LRESULT CALLBACK KWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    KWindow * pWindow;
        
    if ( uMsg==WM_NCCREATE )
    {   
        assert( ! IsBadReadPtr((void *) lParam, sizeof(CREATESTRUCT)) );
        MDICREATESTRUCT * pMDIC = (MDICREATESTRUCT *) ((LPCREATESTRUCT) lParam)->lpCreateParams;
 
        pWindow = (KWindow *) (pMDIC->lParam);
 
        assert( ! IsBadReadPtr(pWindow, sizeof(KWindow)) );
        SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
    }
    else
        pWindow=(KWindow *)GetWindowLong(hWnd, GWL_USERDATA);
 
    if ( pWindow )
        return pWindow->WndProc(hWnd, uMsg, wParam, lParam);
    else
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Он рабочий. Указатель на объект класса передаётся в ((LPCREATESTRUCT) lParam)->lpCreateParams при создании окна функцией CreateWindow.
1
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202
18.05.2015, 15:19  [ТС]
Цитата Сообщение от Enno Посмотреть сообщение
ДЕСАНТУРА,
вот кусок кода от Фень Юаня:
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
class KWindow
{
    virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
    static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
/*
...
*/
};
 
LRESULT KWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch( uMsg )
    {
        case WM_KEYDOWN:
            OnKeyDown(wParam, lParam);
            return 0;
 
        case WM_PAINT:
        {
            PAINTSTRUCT ps; 
                
            BeginPaint(m_hWnd, &ps);
            OnDraw(ps.hdc);
            EndPaint(m_hWnd, &ps);
        }
        return 0;
 
        case WM_PALETTEISCHANGING: // should not happen
            MessageBox(NULL, _T("Hello"), _T("Hi"), MB_OK);
            return 0;
 
        case WM_PALETTECHANGED:
            return OnPaletteChanged(hWnd, wParam);
 
        case WM_QUERYNEWPALETTE:
            return OnQueryNewPalette();
 
        case WM_DESTROY:
            if ( m_bMainWindow )
                PostQuitMessage(0); // main window only
            return 0;
    }
 
   return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 
 
// Generic window procedure passed to WIN32 API, dispatches to KWindow::WndProc
LRESULT CALLBACK KWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    KWindow * pWindow;
        
    if ( uMsg==WM_NCCREATE )
    {   
        assert( ! IsBadReadPtr((void *) lParam, sizeof(CREATESTRUCT)) );
        MDICREATESTRUCT * pMDIC = (MDICREATESTRUCT *) ((LPCREATESTRUCT) lParam)->lpCreateParams;
 
        pWindow = (KWindow *) (pMDIC->lParam);
 
        assert( ! IsBadReadPtr(pWindow, sizeof(KWindow)) );
        SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
    }
    else
        pWindow=(KWindow *)GetWindowLong(hWnd, GWL_USERDATA);
 
    if ( pWindow )
        return pWindow->WndProc(hWnd, uMsg, wParam, lParam);
    else
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Он рабочий. Указатель на объект класса передаётся в ((LPCREATESTRUCT) lParam)->lpCreateParams при создании окна функцией CreateWindow.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
LRESULT CALLBACK KWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    KWindow * pWindow;
        
    if ( uMsg==WM_NCCREATE )
    {   
        assert( ! IsBadReadPtr((void *) lParam, sizeof(CREATESTRUCT)) );
        MDICREATESTRUCT * pMDIC = (MDICREATESTRUCT *) ((LPCREATESTRUCT) lParam)->lpCreateParams;
 
        pWindow = (KWindow *) (pMDIC->lParam);
 
        assert( ! IsBadReadPtr(pWindow, sizeof(KWindow)) );
        SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
    }
    else
        pWindow=(KWindow *)GetWindowLong(hWnd, GWL_USERDATA);
 
    if ( pWindow )
        return pWindow->WndProc(hWnd, uMsg, wParam, lParam);
    else
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
Проверка на валидность игнорится и я получаю краш:
C++
1
2
3
4
5
6
7
8
assert( ! IsBadReadPtr((void *) lParam, sizeof(CREATESTRUCT)) );
        MDICREATESTRUCT * pMDIC = (MDICREATESTRUCT *) ((LPCREATESTRUCT) lParam)->lpCreateParams;
 
        pWindow = (KWindow *) (pMDIC->lParam);
 
        assert( ! IsBadReadPtr(pWindow, sizeof(KWindow)) );
        SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
    }
Добавлено через 10 минут
а именно не передается lParam в экземпляр класса:
C++
1
pWindow = (WindowCreate *) (pMDIC->lParam);
Добавлено через 15 минут
и я так понял, что при каждом новом сообщении, которое будет обрабатывать "обработчик" будет создаваться новый экземпляр класса с новыми переменными, а мне нужно работать с одним и тем же экземпляром и его переменными
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
18.05.2015, 15:57
Цитата Сообщение от ДЕСАНТУРА Посмотреть сообщение
будет создаваться новый экземпляр класса
Показывай как ты создаёшь экземпляр класса и окно.
1
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202
18.05.2015, 16:44  [ТС]
Цитата Сообщение от Enno Посмотреть сообщение
Показывай как ты создаёшь экземпляр класса и окно.
вот весь код:

WindowCreate.cpp

Кликните здесь для просмотра всего текста
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
#include "WindowCreate.h"
 
WindowCreate::WindowCreate(char* WindowClassName, char* WIndowName, WndType type, HWND ParentHWND)
{
    if (WindowRegisterNewClass(WindowClassName))
        InitialWindow(WIndowName, type, ParentHWND);
}
 
bool WindowCreate::WindowRegisterNewClass(char* WindowClassName){
 
    WNDCLASSEX windclassex = { 0 };
 
    windclassex.cbSize = sizeof(WNDCLASSEX);//задаем размер структуры
    windclassex.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC | CS_DBLCLKS;
    windclassex.lpfnWndProc = WindowProc;//WindowEvent;//
    windclassex.cbClsExtra = NULL;
    windclassex.cbWndExtra = NULL;
    windclassex.hInstance = GetModuleHandle(0);
    windclassex.hIcon = LoadIcon(GetModuleHandle(0), 0);//какая иконка будет, можно загрузить с ресурсов
    windclassex.hIconSm = LoadIcon(GetModuleHandle(0), 0);//эта иконка будет отображаться в заголовке окна
    windclassex.hCursor = LoadCursor(GetModuleHandle(0), IDC_ARROW);//какой курсор будет, можно загрузить с ресурсов
    windclassex.hbrBackground = CreateSolidBrush(RGB(160, 160, 160));//цвет заднего фона
    windclassex.lpszMenuName = NULL;//если мы будем использовать меню
    windclassex.lpszClassName = WindowClassName;//название класса окна, можно написать все что угодно
 
    WndClassName = WindowClassName;
 
    if (!RegisterClassExA(&windclassex)) return 0;
 
    return 1;
}
 
bool WindowCreate::InitialWindow(char* WIndowName, WndType type, HWND ParentHWND){
 
    switch (type)
    {
 
    case Parent:
        _hWnd = CreateWindowExA(0, WndClassName, WIndowName, WS_POPUPWINDOW, 0, 0, 800, 400, 0, 0, 0, 0);
        break;
    case Child:
        _hWnd = CreateWindowExA(0, WndClassName, WIndowName, WS_POPUPWINDOW | WS_CHILDWINDOW, 0, 0, 800, 400, ParentHWND, 0, GetModuleHandle(0), 0);
        break;
    case Message:
        _hWnd = CreateWindowExA(0, WndClassName, WIndowName, WS_POPUPWINDOW, 0, 0, 800, 400, 0, 0, GetModuleHandle(0), 0);
        break;
    case Info:
        _hWnd = CreateWindowExA(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, WndClassName, WIndowName, WS_POPUPWINDOW, 0, 0, 800, 400, ParentHWND, 0, GetModuleHandle(0), 0);//WS_EX_TOOLWINDOW чтобы окно не отображалось в панели задач
        break;
    case Test:
        _hWnd = CreateWindowExA(0, WndClassName, WIndowName, WS_OVERLAPPEDWINDOW, 0, 0, 800, 400, ParentHWND, 0, GetModuleHandle(0), 0);
        break;
    }
 
    ShowWindow(_hWnd, SW_SHOW);
 
    return 1;
}
 
LRESULT WindowCreate::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_LBUTTONDOWN:
        printf("%d\n", test);
    }
 
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
 
// Generic window procedure passed to WIN32 API, dispatches to KWindow::WndProc
LRESULT CALLBACK WindowCreate::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    WindowCreate * pWindow = nullptr;
 
    if (uMsg == WM_NCCREATE)
    {
        assert(!IsBadReadPtr((void *) lParam, sizeof(CREATESTRUCT)));
 
            MDICREATESTRUCT * pMDIC = (MDICREATESTRUCT *) ((LPCREATESTRUCT) lParam)->lpCreateParams;
 
            if (!IsBadReadPtr(pMDIC, sizeof(MDICREATESTRUCT))){
                pWindow = (WindowCreate *) (pMDIC->lParam);
                
            }
                
 
            assert(!IsBadReadPtr(pWindow, sizeof(WindowCreate)));
        SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
    }
    else
        pWindow = (WindowCreate *) GetWindowLong(hWnd, GWL_USERDATA);
 
    if (pWindow)
        return pWindow->WndProc(hWnd, uMsg, wParam, lParam);
    else
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


WindowCreate.h

Кликните здесь для просмотра всего текста
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
#pragma once
 
#include "Includes.h"
 
class WindowCreate
{
 
public:
    typedef enum WndStyle :DWORD{
 
        NoBorder = WS_POPUPWINDOW,
        Border = WS_OVERLAPPEDWINDOW
 
    };
    typedef enum WndType:INT{
 
        Parent,
        Child,
        Message,
        Info,
        Test
    };
 
    WindowCreate(char* WindowClassName, char* WIndowName, WndType type, HWND ParentHWND);
    bool WindowRegisterNewClass(char* WindowClassName);
    bool InitialWindow(char* WIndowName, WndType type, HWND ParentHWND);
    char* WndClassName;
    HWND _hWnd;
    bool LMClickD;
    bool LMClickU;
    int test = 0;
 
    virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
    static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
    
};


подключаемые библиотеки:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
#pragma once 
 
#define _CRT_SECURE_NO_WARNINGS //для sprintf
 
#include <windows.h>
#include <fstream>
#include <io.h>
#include <iostream>
#include <fcntl.h> //Console
#include <string>
#include <tlhelp32.h>//Узнавать инфу о процессе
#include <assert.h>//Для асерта


создаю экземпляр класса в WinMain:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int _stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpCmdLine, int nCmdShow)
{
    tool.ConsoleCreate();
 
    WindowCreate wnd = WindowCreate("Basa", "Parent Window1", WindowCreate::WndType::Test, 0);
 
    MSG msg;
 
    while (1)
    {
        if (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)){
            TranslateMessage(&msg);
            DispatchMessageW(&msg);
        }
 
        Sleep(1);
    }
 
    tool.ConsoleDestroy();
 
    return 0;
}
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
18.05.2015, 17:28
Лучший ответ Сообщение было отмечено ДЕСАНТУРА как решение

Решение

Цитата Сообщение от ДЕСАНТУРА Посмотреть сообщение
CreateWindowExA(0, WndClassName, WIndowName, WS_POPUPWINDOW, 0, 0, 800, 400, 0, 0, 0, 0);
Да у тебя же во всех функциях последнего параметра нет. Разумеется что сообщение WM_NCCREATE не получит ничего.
1
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202
18.05.2015, 18:36  [ТС]
а что я туда должен передать? указатель на текущий класс?

Добавлено через 56 минут
если я передаю указатель то при передачи сообщений в функции происходит краш:
C++
1
2
 if (pWindow)
        return pWindow->WndProc(hWnd, uMsg, wParam, lParam);
так как она виртуальная, я убрал с нее спецификатор vitrtual получил 2 косяка:
1. Функция заработала - при выводе переменной "test" из класса она выдала неправильное значение(мусор)
2. Если создать 2 и более окон - то обработчик будет работать только у первого создавшегося окна, у других не будет.
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
18.05.2015, 18:44
Цитата Сообщение от ДЕСАНТУРА Посмотреть сообщение
а что я туда должен передать?
LPCREATESTRUCT
Вот тебе файлы, разбирайся.
Вложения
Тип файла: rar win.rar (3.6 Кб, 17 просмотров)
1
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202
18.05.2015, 18:59  [ТС]
спасибо помог, все работает как нужно.

Добавлено через 2 минуты
маленький вопросик - нужно ли уничтожать виртуальный обработчик при разрушении окна?
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
19.05.2015, 05:05
Цитата Сообщение от ДЕСАНТУРА Посмотреть сообщение
уничтожать виртуальный обработчик
Чего уничтожать?
0
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202
19.05.2015, 15:32  [ТС]
Цитата Сообщение от Enno Посмотреть сообщение
Чего уничтожать?
да все уже сделал обычным обработчик не виртуальным - боялся утечки памяти, функция то виртуальная и память под нее выделяется динамически, поэтому после уничтожения окна нужно эту память освобождать вроде
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
19.05.2015, 18:20
Цитата Сообщение от ДЕСАНТУРА Посмотреть сообщение
функция то виртуальная и память под нее выделяется динамически
Чё? Функция одна для всех экземпляров класса.
0
6 / 6 / 5
Регистрация: 25.02.2015
Сообщений: 202
19.05.2015, 20:34  [ТС]
Цитата Сообщение от Enno Посмотреть сообщение
Чё? Функция одна для всех экземпляров класса.
нет у каждого экземпляра класса она разная, проверено лично
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
20.05.2015, 03:21
Цитата Сообщение от ДЕСАНТУРА Посмотреть сообщение
нет у каждого экземпляра класса она разная, проверено лично
Мы сейчас говорим про функцию. Она существует в единственном экземпляре, ибо неизменна.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
20.05.2015, 03:21
Помогаю со студенческими работами здесь

Обработчик событий и работа с объектами класса object
Всем суток времени доброго! Помогите начинающему дубу в следующие проблеме, если вас не затруднит. У меня есть обработчик события...

Повесить обработчик событий на все элементы определенного класса
есть код: onload = function(){ var a = document.querySelectorAll(&quot;p.kor a&quot;); alert(a.href); ...

Нужен батник для создания отчета событий и их свойств из журнала событий на локальном компьютере
Пакетный файл, предназначенный для создания отчета событий и их свойств из журнала событий на локальном компьютере. Журналы событий:...

Автоматизация создания событий + время выполнения событий
Подскажите, имею 9 button как автоматически с помощью цикла прописать выполнения события для всех этих кнопок. И ещё вопрос как понять за...

обработчик событий
Как сделать обработчик кнопки Редактировать запись и Сохранить запись..при работе с бД,где данные беруться из аксеса, отражаются в DBGrid...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru