Nano Hash - криптовалюты, майнинг, программирование

Член класса как-то нехотя меняется

У меня есть два следующих класса CDialog, созданных для создания диалоговых окон из шаблонов, и класс CMainDialog, который является производным от CDialog и имеет некоторые методы, управляющие элементами управления в диалоговых окнах.

class CDialog
    {
    public:
        CDialog(DWORD dwTemplate) : m_dwTemplateID(dwTemplate), m_hWnd(NULL) {};
        virtual ~CDialog() {};

        static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

        virtual BOOL Create(HINSTANCE hInstance, HWND hParent = NULL);

        BOOL Show(BOOL bShow);
    private:
        DWORD m_dwTemplateID;

    protected:
        HWND m_hWnd;
        virtual INT_PTR HandleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    };

// Реализация базового диалога

#include "BaseDialog.h"

//statics

INT_PTR CALLBACK Inc::CDialog::DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    Inc::CDialog* pDialog = nullptr;

    if(uMsg == WM_INITDIALOG)
    {
        //save address of the CDialog-object into the dialog´s userdata
        pDialog = (Inc::CDialog*)lParam;
        SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pDialog);
    }
    else
    {
        //get the pointer
        pDialog = (Inc::CDialog*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
    }

    if(pDialog)
    {
        //handle messages
        return pDialog->HandleMessages(hWnd, uMsg, wParam, lParam);
    }

    return FALSE;       //!pDialog
}

INT_PTR Inc::CDialog::HandleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_CLOSE:
            DestroyWindow(m_hWnd);
        return TRUE;
    case WM_DESTROY:
            PostQuitMessage(0);
            return TRUE;
    };

    return FALSE;       //Message not handled => system will take action
}

BOOL Inc::CDialog::Create(HINSTANCE hInstance, HWND hParent)
{
    m_hWnd = CreateDialogParam(hInstance, MAKEINTRESOURCE(m_dwTemplateID), hParent, DialogProc, (LPARAM)this);
    if(m_hWnd == NULL)
        return FALSE;

    return TRUE;
}

//return values: TRUE => window was previously visible, FALSE otherwise
BOOL Inc::CDialog::Show(BOOL bShow)
{
    if(bShow)
        return ShowWindow(m_hWnd, SW_SHOWNORMAL);
    return ShowWindow(m_hWnd, SW_HIDE);
}

// CMainDialog

class CMainDialog :
        public Inc::CDialog
    {
    public:
        CMainDialog(DWORD dwTemplateID);
        virtual ~CMainDialog(void);

        virtual INT_PTR HandleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

    private:
        static const char m_szDates[8][14];

        //Dialog control item
        HWND m_hDateComboBox;
        HWND m_hItemListBox;
        HWND m_hDescriptionEditBox;
        HWND m_hButtonClose;
        HWND m_hButtonSave;
        HWND m_hButtonDelete;

        //get save the control item handles
    public:
        void GetControlHandles();
    public:
        void PopulateDateComboBox();
    };

// Реализация диалога CMain

#include "MainDialog.h"
#include <WindowsX.h>
#include "resource.h"
#include <stdexcept>

//statics
const char Inc::CMainDialog::m_szDates[8][14] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Single Event"};

Inc::CMainDialog::CMainDialog(DWORD dwTemplateID) : CDialog(dwTemplateID)
{
}


Inc::CMainDialog::~CMainDialog(void)
{
}

//adds the entries in m_szDates to the Combo Box for choosing the date
void Inc::CMainDialog::PopulateDateComboBox()
{
    for(unsigned short s = 0; s < 8; s++)
    {
        if(ComboBox_AddString(m_hDateComboBox, m_szDates[s]) <= CB_ERR)
            throw(std::runtime_error("ComboBox_AddString() failed"));
    }
}

INT_PTR Inc::CMainDialog::HandleMessages(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
    case WM_INITDIALOG:
            this->GetControlHandles();    // It happens here !!!!!!! <====
            this->PopulateDateComboBox();
        return TRUE;
    }

    return Inc::CDialog::HandleMessages(hWnd, uMsg, wParam, lParam);        //if message isnt handled here, default handling
}

void Inc::CMainDialog::GetControlHandles()
{
    //Get Control window handles
    m_hDateComboBox = GetDlgItem(m_hWnd, IDC_COMBO_DAY);
    m_hItemListBox = GetDlgItem(m_hWnd, IDC_LIST);
    m_hDescriptionEditBox = GetDlgItem(m_hWnd, IDC_EDIT_DESCRIPTION);
    m_hButtonClose = GetDlgItem(m_hWnd, IDC_BUTTON_CLOSE);
    m_hButtonSave = GetDlgItem(m_hWnd, IDC_BUTTON_SAVE_CHANGE);
    m_hButtonDelete = GetDlgItem(m_hWnd, IDC_BUTTON_DELETE_ITEM);
}

Проблема, с которой я сталкиваюсь, заключается в том, что в функции-члене CMainDialog :: HandleMessages (), когда должен обрабатываться WM_INITDIALOG, член m_hWnd имеет значение NULL даже несмотря на то, что функция CDialog :: Create () завершилась успешно и вернула дескриптор окна в m_hWnd.

Процедура CDialog :: DialogProc, похоже, работает таким образом, что она получает правильный адрес из LPARAM WM_INITDIALOG и позволяет указателю pDialog указывать вправо объект и вызовите его функции-члены.

Может быть, Вы видите, что я упустил или где сделал не так.

Заранее спасибо

08.05.2011

Ответы:


1

ваше сообщение WM_INITDIALOG обрабатывается во время вызова CreateDialog, а присвоение m_hWnd (результат CreateDialog) выполняется после завершения CreateDialog.

Решение: передать hWnd в GetControlHandle (HWND hWnd) или установить m_hWnd в WM_INITDIALOG Базового класса.

08.05.2011

2

Чтобы исправить это, добавьте pDialog->m_hWnd = hWnd; в обработку WM_INITDIALOG:

if(uMsg == WM_INITDIALOG)
{
    //save address of the CDialog-object into the dialog´s userdata
    pDialog = (Inc::CDialog*)lParam;
    SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pDialog);
    pDialog->m_hWnd = hWnd;
}

Это гарантирует, что m_hWnd будет установлен перед любым вызовом HandleMessage

08.05.2011
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..


© 2024 nano-hash.ru, Nano Hash - криптовалюты, майнинг, программирование