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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Свой класс CWindow, субклассирование, окно из ресурсов не обрабатыв. сообщения 
:(
    Опции темы
Alca
Дата 29.7.2009, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Есть класс:

Код

//---------------------------------------------------------------------------
class CXWindow {
    public:
                                 CXWindow     ();
        virtual                 ~CXWindow     () = 0;
        
        BOOL                     bCreate      (INT iID, HWND hParent, INT iLeft, INT iTop, INT iWidth, INT iHeight, ULONG ulStyle, ULONG ulExStyle);
        BOOL                     bCreateRes   (INT iID, HWND hParent);

static    BOOL                     bIsDialog    (HWND hWnd);
        //...
     
    protected:
        HWND                     _m_hWnd;
        BOOL                     bRegisterClassEx(const WNDCLASSEX *cpwcWndClassEx);
        BOOL                     bCreateEx       (ULONG ulExStyle, const std::string &csClassName, const std::string &csText, ULONG ulStyle, INT iLeft, INT iTop, INT iWidth, INT iHeight, HWND hParent, INT iID, LPVOID lpParam);
     static  LRESULT CALLBACK s_BaseWndProc   (HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
     virtual LRESULT          pWndProc        (HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam, PBOOL pbProcessed);
        //...
};  
//---------------------------------------------------------------------------


//...
//---------------------------------------------------------------------------
//TODO: + CXWindow
CXWindow::CXWindow() :
    _m_hWnd      (0),
    _m_ulExStyle (0),
    _m_sClassName(""),
    _m_sText     (""),
    _m_ulStyle   (0),
    _m_iWidth    (0),
    _m_iHeight   (0),
    _m_iLeft     (0),
    _m_iTop      (0),
    _m_hParent   (NULL),        
    _m_iMenu     (0),
    _m_Font      (NULL),
    _m_bIsFrame  (FALSE)
{
    LOG();
}
//---------------------------------------------------------------------------
//TODO: + ~CXWindow
/*virtual*/CXWindow::~CXWindow () {
    LOG();

    BOOL bRes = FALSE;
    
    /*DEBUG*/XASSERT(NULL != _m_Font);
    bRes = ::DeleteObject(_m_Font);    _m_Font = NULL;
    /*DEBUG*/XASSERT(FALSE != bRes);    
}
//---------------------------------------------------------------------------



/****************************************************************************
*    public
*
*****************************************************************************/

//...

//---------------------------------------------------------------------------
//TODO: + bIsDialog
BOOL CXWindow::bIsDialog(HWND hWnd) {
    /*DEBUG*///not need

    UINT uiRes = 0;

    uiRes = ::GetClassWord(hWnd, GCW_ATOM);
    /*DEBUG*/XASSERT_RET(0 != uiRes, FALSE);

    CHECK_RET(32770 != uiRes, FALSE);

    return TRUE;
}
//---------------------------------------------------------------------------

//...

/****************************************************************************
*    protected
*
*****************************************************************************/

//...

//---------------------------------------------------------------------------
//TODO: + bRegisterClassEx
BOOL CXWindow::bRegisterClassEx(const WNDCLASSEX *cpwcWndClassEx) {
    /*DEBUG*/XASSERT_RET(NULL != cpwcWndClassEx, FALSE);

    BOOL bRes = FALSE;

    bRes = ::RegisterClassEx(cpwcWndClassEx);
    /*DEBUG*/XASSERT_RET(FALSE != bRes, FALSE);

    return TRUE;
}
//---------------------------------------------------------------------------
//TODO: + bCreateEx
BOOL CXWindow::bCreateEx(ULONG ulExStyle, const std::string &csClassName, const std::string &csText, ULONG ulStyle, 
                         INT iLeft, INT iTop, INT iWidth, INT iHeight, HWND hParent, INT iID, LPVOID lpParam)
{
    /*DEBUG*/XASSERT_RET(NULL  == _m_hWnd,             NULL);
    /*DEBUG*/XASSERT_RET(false == csClassName.empty(), NULL);

    BOOL bRes = FALSE;

    _m_hWnd = ::CreateWindowEx(_m_ulExStyle | ulExStyle, _m_sClassName.c_str(), _m_sText.c_str(), _m_ulStyle | ulStyle, iLeft, iTop, iWidth, iHeight, hParent, (HMENU)iID, CXApplication::hGetInstance(), lpParam);
    /*DEBUG*/XASSERT_RET(NULL != _m_hWnd, FALSE);

    bRes = bSetDefaultFont();
    CHECK_RET(FALSE != bRes, FALSE);

    //-------------------------------------
    //переопределяем поля класса
    _m_ulExStyle  = _m_ulExStyle | ulExStyle;    
    _m_sClassName = _m_sClassName;
    _m_sText      = _m_sText;
    _m_ulStyle    = _m_ulStyle | ulStyle;
    _m_iLeft      = iLeft;
    _m_iTop       = iTop;
    _m_iWidth     = iWidth; 
    _m_iHeight    = iHeight;
    _m_hParent    =    hParent;    
    _m_iMenu      = iID;

    return TRUE;
}
//---------------------------------------------------------------------------
//TODO: + bCreate
BOOL CXWindow::bCreate(INT iID, HWND hParent, INT iLeft, INT iTop, INT iWidth, INT iHeight, ULONG ulStyle, ULONG ulExStyle) {
    /*DEBUG*/XASSERT_RET(NULL == _m_hWnd, FALSE);

    BOOL bRes = FALSE;

    //-------------------------------------
    //если это окно - WNDCLASSEX, если контрол - ничего
    if (TRUE == _m_bIsFrame) {
        //-------------------------------------
        //Set the default data for the window class.
        //These can be reset in the derived class's constructor.
        WNDCLASSEX _m_WndClass = {0};

        _m_WndClass.hInstance     = CXApplication::hGetInstance();    
        _m_WndClass.lpszClassName = _m_sClassName.c_str();
        _m_WndClass.lpfnWndProc   = (WNDPROC)s_BaseWndProc;        //This function is called by windows
        _m_WndClass.style         = CS_DBLCLKS;                    //Catch double-clicks
        _m_WndClass.cbSize        = sizeof(WNDCLASSEX);
        _m_WndClass.hIcon         = NULL;                        //_m_hIcon;    //LoadIcon (hInstance, 0);
        _m_WndClass.hIconSm       = NULL;                        //LoadIcon (hInstance, 0);
        _m_WndClass.hCursor       = NULL;                        //LoadCursor (NULL, IDC_ARROW);
        _m_WndClass.lpszMenuName  = NULL;
        _m_WndClass.cbClsExtra    = 0;                            //256;        //No extra bytes after the window class
        _m_WndClass.cbWndExtra    = 0;                            //dialog box not from resource file
        _m_WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);

        bRes = bRegisterClassEx(&_m_WndClass);
        ////CHECK_RET(FALSE == bRes, FALSE);
    } else {
        //контролы
    }

    bRes = bCreateEx(ulExStyle, _m_sClassName, _m_sText, ulStyle, iLeft, iTop, iWidth, iHeight, hParent, iID, (VOID *)this);
    CHECK_RET(FALSE == bRes, FALSE);

    return TRUE;
}
//---------------------------------------------------------------------------
BOOL CXWindow::bCreateRes(INT iID, HWND hParent) {
    BOOL bRes = FALSE;

    //-------------------------------------
    //если это окно - WNDCLASSEX, если контрол - ::GetDlgItem
    if (TRUE == _m_bIsFrame) {
        //-------------------------------------
        //Register the window class
        WNDCLASSEX _m_WndClass = {0};    
    
        _m_WndClass.hInstance     = CXApplication::hGetInstance();        
        _m_WndClass.lpszClassName = _m_sClassName.c_str();
        _m_WndClass.lpfnWndProc   = s_BaseWndProc;    //This function is called by windows
        _m_WndClass.style         = CS_DBLCLKS;                //Catch double-clicks
        _m_WndClass.cbSize        = sizeof(WNDCLASSEX);
        _m_WndClass.hIcon         = NULL;                    //LoadIcon (hInstance, 0);
        _m_WndClass.hIconSm       = NULL;                        //LoadIcon (hInstance, 0);
        _m_WndClass.hCursor       = NULL;                        //LoadCursor (NULL, IDC_ARROW);
        _m_WndClass.lpszMenuName  = NULL;
        _m_WndClass.cbClsExtra    = 256;                        //No extra bytes after the window class
        _m_WndClass.cbWndExtra    = DLGWINDOWEXTRA/*0*/;        //используем диалог с ресурса
        _m_WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);

        bRes = bRegisterClassEx(&_m_WndClass);
        ////CHECK_RET(FALSE == bRes, FALSE);
    
        _m_hWnd = ::CreateDialog(CXApplication::hGetInstance(), MAKEINTRESOURCE(iID), hParent, (DLGPROC)s_BaseWndProc);
        /*DEBUG*/XASSERT_RET(NULL != _m_hWnd, FALSE);
    } else  {
        _m_hWnd = ::GetDlgItem(hParent, iID);
        /*DEBUG*/XASSERT_RET(NULL != _m_hWnd, FALSE);
    }


    return TRUE;
}
//---------------------------------------------------------------------------
//TODO: + s_BaseWndProc
LRESULT CALLBACK CXWindow::s_BaseWndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) {
    /*DEBUG*/XASSERT_RET(NULL != hWnd, NULL);

    //A pointer to the object is passed in the CREATESTRUCT
    if (WM_NCCREATE == uiMsg) {
        ::SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)((LPCREATESTRUCT)lParam)->lpCreateParams);
    }

    BOOL    bProcessed = FALSE;
    LRESULT lResult    = NULL;

    //Retrieve the pointer
    CXWindow *pObj = (CXWindow *)::GetWindowLongPtr(hWnd, GWLP_USERDATA);

    //Filter message through child classes
    if (NULL != pObj) {
        lResult = pObj->pWndProc(hWnd, uiMsg, wParam, lParam, &bProcessed);
    }

    if (TRUE == bProcessed) {
        return lResult;
    } else {
        //////If message was unprocessed, send it back to Windows.
        ////return ::DefWindowProc(hWnd, uiMsg, wParam, lParam);
        
        if (TRUE == bIsDialog(hWnd)) {
            //диалог
            return 0;    //<--- окно не реагирует ни на какие девствия, но нормально можно перемещять мышкой
            //return pObj->pWndProc(hWnd, uiMsg, wParam, lParam, &bProcessed);    //<--- окно не реагирует ни на какие девствия, нельзя перемещять мышкой
        } else {
            //окно
            return ::DefWindowProc(hWnd, uiMsg, wParam, lParam);
        }
    }
}
//---------------------------------------------------------------------------
//TODO: + pWndProc
/*virtual*/LRESULT CXWindow::pWndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam, PBOOL pbProcessed) {
    /*DEBUG*/XASSERT_RET(NULL != _m_hWnd, NULL);

    //This may be overridden to process messages.
    *pbProcessed = FALSE;

    return NULL;
}
//---------------------------------------------------------------------------

//...


От него наследую класс CXFrame, потом CXMyFrame.
Если создаю окно с помощью ::CreateWindowEx:

Код

CMainFrame MainFrame;
MainFrame.bCreate(0, HWND_DESKTOP, 400, 400, 600, 430, 0, 0);

    
то все нормально работает, а если из ресурсов:

Код

CMainFrame MainFrame;
MainFrame.bCreateRes(IDD_DIALOGBAR, HWND_DESKTOP);

    
то окно содается, но не реагирует ни на какие действия (не идет обработка сообщений),
только можно перемещять мышкой.
Где-то косяк в методе s_BaseWndProc... 
Если чего-то в коде не хватает - выложу.

Это сообщение отредактировал(а) Alca - 29.7.2009, 15:59


--------------------
PM WWW ICQ Skype Jabber   Вверх
GremlinProg
Дата 29.7.2009, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Alca @  29.7.2009,  17:54 Найти цитируемый пост)
Где-то косяк в методе s_BaseWndProc... 

по-видимому, проблема в самом подходе к объединению функционала диалога и обычного окна в одном сишном классе:

если свойство Class в шаблоне указывает на нормальный класс окна,
то CreateDialog создает окно уже не класса 32770, а именно этого класса, указанного в свойстве Class )

короче говоря, основная ошибка в функции bIsDialog, она никогда не вернет TRUE
вот с этого момента и разбирай функционал дальше:

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

т.е. это не синтаксическая ошибка, а логическая, ты создал окно диалогового класса,
но не даешь этому классу с ним работать,
полностью перекрыл функционал предка,
точнее даже исключил предка из цепочки наследования (т.к. DefWindowProc все же вызываешь)

мы ведь уже обсуждали проблему идентификации диалога при суперклассинге,
изнутри твоего класса эту проблему решить можно, если сохранять процедуру класса-предка в самом объекте,
а в последствии, изучать ее: если она равна DefDlgProc, то это диалог, иначе - нет,
конечно, это верно только при условии, что цепочка предков состоит только из одного класса
(судя по коду, этого более чем достаточно)

т.е. заведи в сишном классе поле
Код

WNDPROC StdProc;

а заполняй его только в методах: bCreateEx, bCreate и bCreateRes
для всех методов инициируй его в DefWindowProc, кроме bCreateRes, тут ставь DefDlgProc
тогда в s_BaseWndProc вместо компаратора bIsDialog ставь просто вызов
Код

return ::CallWindowProc(StdProc,...);



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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Цитата

короче говоря, основная ошибка в функции bIsDialog, она никогда не вернет TRUE

Отладчиком заходил в TRUE.

Добавлено через 5 минут и 48 секунд
 smile 

Это сообщение отредактировал(а) Alca - 29.7.2009, 21:02

Присоединённый файл ( Кол-во скачиваний: 8 )
Присоединённый файл  _Screenshot_.PNG 32,97 Kb


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 29.7.2009, 22:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Код

LRESULT CALLBACK CXWindow::s_BaseWndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) {
    /*DEBUG*/XASSERT_RET(NULL != hWnd, NULL);

    //A pointer to the object is passed in the CREATESTRUCT
    if (WM_INITDIALOG/*WM_NCCREATE*/ == uiMsg) {
        /* >>> .......... валиться здесь .............. <<< */
        ::SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)((LPCREATESTRUCT)lParam)->lpCreateParams);
    }


    BOOL    bProcessed = FALSE;
    LRESULT lResult    = NULL;

    //Retrieve the pointer
    CXWindow *pObj = (CXWindow *)::GetWindowLongPtr(hWnd, GWLP_USERDATA);

    //Filter message through child classes
    if (NULL != pObj) {
        lResult = pObj->pWndProc(hWnd, uiMsg, wParam, lParam, &bProcessed);
    }

        if (TRUE == bProcessed) {
            return lResult;
        } else {
            //////If message was unprocessed, send it back to Windows.
            ////return ::DefWindowProc(hWnd, uiMsg, wParam, lParam);
            
            if (TRUE == bIsDialog(hWnd)) {
                //диалог
                return 0;
                //return pObj->pWndProc(hWnd, uiMsg, wParam, lParam, &bProcessed);
            } else {
                //окно
                return ::DefWindowProc(hWnd, uiMsg, wParam, lParam);
            }
        }
}


Это сообщение отредактировал(а) Alca - 29.7.2009, 22:37


--------------------
PM WWW ICQ Skype Jabber   Вверх
GremlinProg
Дата 30.7.2009, 00:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Alca @  29.7.2009,  22:57 Найти цитируемый пост)
Отладчиком заходил в TRUE.

Цитата(GremlinProg @  29.7.2009,  19:46 Найти цитируемый пост)
если свойство Class в шаблоне указывает на нормальный класс окна

иначе в твою процедуру окна он не войдет
не войдет именно как в процедуру окна,
т.к. будет создано стандартное диалоговое окно, класса 32770, а у него процедура окна DefDlgProc
Цитата(Alca @  29.7.2009,  17:54 Найти цитируемый пост)
::CreateDialog(CXApplication::hGetInstance(), MAKEINTRESOURCE(iID), hParent, (DLGPROC)s_BaseWndProc);

Цитата(Alca @  29.7.2009,  17:54 Найти цитируемый пост)
_m_WndClass.lpfnWndProc   = s_BaseWndProc;    //This function is called by windows

опять смешиваешь диалоговую процедуру и процедуру окна в одну кучу,
нельзя назначать одну процедуру в обе эти сущности, т.к. логика у них разная,
в случае суперклассинга диалога, последний параметр, передаваемый функции CreateDialog, должен быть NULL!:
Код

::CreateDialog(CXApplication::hGetInstance(), MAKEINTRESOURCE(iID), hParent, NULL);

в брейкпойнте, у тебя работает диалоговая процедура, а не процедура окна,
а между ними огромная разница:
http://msdn.microsoft.com/en-us/library/ms645469(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms633573(VS.85).aspx
я же объяснял


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Спасибо.
Цитата

мы ведь уже обсуждали проблему идентификации диалога при суперклассинге,
изнутри твоего класса эту проблему решить можно, если сохранять процедуру класса-предка в самом объекте,
а в последствии, изучать ее: если она равна DefDlgProc, то это диалог, иначе - нет,
конечно, это верно только при условии, что цепочка предков состоит только из одного класса
(судя по коду, этого более чем достаточно)

т.е. заведи в сишном классе полекод 
Код

  WNDPROC StdProc;




а заполняй его только в методах: bCreateEx, bCreate и bCreateRes
для всех методов инициируй его в DefWindowProc, кроме bCreateRes, тут ставь DefDlgProc
тогда в s_BaseWndProc вместо компаратора bIsDialog ставь просто вызовкод 
Код

  return ::CallWindowProc(StdProc,...);


 smile 


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 30.7.2009, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Мне хотя бы полноценный примерчик субклассирования с ::CreateDialog (без ::CreateWindowEx)

Добавлено через 12 минут и 3 секунды
Код

_m_WndClass.lpfnWndProc   = NULL; //s_BaseWndProc;    //This function is called by windows
_m_hWnd = ::CreateDialog(CXApplication::hGetInstance(), MAKEINTRESOURCE(iID), hParent, NULL/*(DLGPROC)s_BaseWndProc*/);

Теперь вообще не попадаю в s_BaseWndProc.  smile 


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 30.7.2009, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



 smile 


--------------------
PM WWW ICQ Skype Jabber   Вверх
GremlinProg
Дата 30.7.2009, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



хорошо, привожу пример суперклассинга для диалога,
а чтобы ни кого особенно не напрягал объем кода, объясняю:
я просто создал обычный проект Win32 Project, так что по большей части,
это чуть-чуть подправленный стандартный Win32-шаблон
Код

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;                                // current instance
TCHAR szTitle[MAX_LOADSTRING];                    // The title bar text

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
HWND hWnd;

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow){
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: Place code here.
    MSG msg;
    HACCEL hAccelTable;

    // Initialize global strings
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance,nCmdShow))
    {
        return FALSE;
    }

    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_INHERITEDDIALOG));

    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if ( !IsDialogMessage( hWnd, &msg ) && !TranslateAccelerator(msg.hwnd, hAccelTable, &msg) )
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = DLGWINDOWEXTRA;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_INHERITEDDIALOG));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName    = NULL;
    wcex.lpszClassName    = _T("Мой диалоговый класс");
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance,int nCmdShow)
{
   hInst = hInstance; // Store instance handle in our global variable
   hWnd = ::CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),HWND_DESKTOP,NULL);
   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd,nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND    - process the application menu
//  WM_PAINT    - Paint the main window
//  WM_DESTROY    - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_ABOUT:
            ::DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            ::DestroyWindow(hWnd);
            break;
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: Add any drawing code here...
        EndPaint(hWnd, &ps);
        break;
    case WM_CLOSE:
        return ::DefWindowProc(hWnd,message,wParam,lParam);
    case WM_DESTROY:
        PostQuitMessage( S_OK );
        break;
    }
    return::CallWindowProc(DefDlgProc,hWnd, message, wParam, lParam);
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

файл ресурсов:
Код

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef APSTUDIO_INVOKED
#include "targetver.h"
#endif
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// Russian resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
#ifdef _WIN32
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
#pragma code_page(1251)
#endif //_WIN32

/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_DIALOG1 DIALOGEX 0, 0, 316, 185
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Мой диалог"
MENU IDC_INHERITEDDIALOG
CLASS "Мой диалоговый класс"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,205,164,50,14
    PUSHBUTTON      "Cancel",IDCANCEL,259,164,50,14
    LTEXT           "Диалоговый контрол:",IDC_STATIC,32,44,77,12
    EDITTEXT        IDC_EDIT1,113,42,97,14,ES_AUTOHSCROLL
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO 
BEGIN
    IDD_DIALOG1, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 309
        TOPMARGIN, 7
        BOTTOMMARGIN, 178
    END
END
#endif    // APSTUDIO_INVOKED

#endif    // Russian resources
/////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_INHERITEDDIALOG     ICON                    "InheritedDialog.ico"
IDI_SMALL               ICON                    "small.ico"

/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDC_INHERITEDDIALOG MENU 
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "E&xit",                       IDM_EXIT
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About ...",                  IDM_ABOUT
    END
END


/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//

IDC_INHERITEDDIALOG ACCELERATORS 
BEGIN
    "?",            IDM_ABOUT,              ASCII,  ALT
    "/",            IDM_ABOUT,              ASCII,  ALT
END


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About InheritedDialog"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    ICON            128,IDC_STATIC,14,14,21,20
    LTEXT           "InheritedDialog, Version 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX
    LTEXT           "Copyright (C) 2009",IDC_STATIC,42,26,114,8
    DEFPUSHBUTTON   "OK",IDOK,113,41,50,14,WS_GROUP
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO 
BEGIN
    IDD_ABOUTBOX, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 163
        TOPMARGIN, 7
        BOTTOMMARGIN, 55
    END
END
#endif    // APSTUDIO_INVOKED


#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#ifndef APSTUDIO_INVOKED\r\n"
    "#include ""targetver.h""\r\n"
    "#endif\r\n"
    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
    "#include ""windows.h""\r\n"
    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE 
BEGIN
    IDS_APP_TITLE           "InheritedDialog"
    IDC_INHERITEDDIALOG     "INHERITEDDIALOG"
END

#endif    // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED


Добавлено через 1 минуту и 16 секунд
да, совсем забыл, файл Resource.h:
Код

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by InheritedDialog.rc
//
#define IDC_MYICON                      2
#define IDD_INHERITEDDIALOG_DIALOG      102
#define IDS_APP_TITLE                   103
#define IDD_ABOUTBOX                    103
#define IDM_ABOUT                       104
#define IDM_EXIT                        105
#define IDI_INHERITEDDIALOG             107
#define IDI_SMALL                       108
#define IDC_INHERITEDDIALOG             109
#define IDR_MAINFRAME                   128
#define IDD_DIALOG1                     129
#define IDC_EDIT1                       1000
#define IDC_STATIC                      -1

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC                     1
#define _APS_NEXT_RESOURCE_VALUE        130
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE           110
#endif
#endif




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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Попробую чего-то наваять...


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 30.7.2009, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Что-то нихрена не получается:  smile 
Код

//---------------------------------------------------------------------------
BOOL CXWindow::bCreateRes(INT iID, HWND hParent) {
    BOOL bRes = FALSE;

    //-------------------------------------
    //Register the window class
    WNDCLASSEX _m_WndClass = {0};    

    _m_WndClass.hInstance     = CXApplication::hGetInstance();        
    _m_WndClass.lpszClassName = _m_sClassName.c_str();
    _m_WndClass.lpfnWndProc   = NULL/*s_BaseWndProc*/;    
    _m_WndClass.style         = CS_DBLCLKS;                
    _m_WndClass.cbSize        = sizeof(WNDCLASSEX);
    _m_WndClass.hIcon         = NULL;                    
    _m_WndClass.hIconSm       = NULL;                        
    _m_WndClass.hCursor       = NULL;                        
    _m_WndClass.lpszMenuName  = NULL;
    _m_WndClass.cbClsExtra    = 256;                       
    _m_WndClass.cbWndExtra    = DLGWINDOWEXTRA;        
    _m_WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);

    bRes = bRegisterClassEx(&_m_WndClass);
    CHECK_RET(FALSE == bRes, FALSE);

    _m_hWnd = ::CreateDialog(CXApplication::hGetInstance(), MAKEINTRESOURCE(iID), hParent, (DLGPROC)NULL/*s_BaseWndProc*/);
    /*DEBUG*/XASSERT_RET(NULL != _m_hWnd, FALSE);

    //-------------------------------------
    //переопределяем поля класса
    RECT rcRect = {0};
    ::GetClientRect(_m_hWnd, &rcRect);

    _m_ulExStyle  = GetWindowExStyle(_m_hWnd);    
    _m_sClassName = _m_sClassName;              
    _m_sText      = sGetText();
    _m_ulStyle    = GetWindowStyle(_m_hWnd);    
    _m_iLeft      = rcRect.left;
    _m_iTop       = rcRect.top;
    _m_iWidth     = rcRect.right; 
    _m_iHeight    = rcRect.bottom;
    _m_hParent    =    hParent;    
    _m_iMenu      = iID;

    return TRUE;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK CXWindow::s_BaseWndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) {
    /*DEBUG*/XASSERT_RET(NULL != hWnd, NULL);

    //A pointer to the object is passed in the CREATESTRUCT
    if (WM_INITDIALOG/*WM_NCCREATE*/ == uiMsg) {
        //::SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)((LPCREATESTRUCT)lParam)->lpCreateParams);
        ::SetWindowLong(hWnd, DWL_DLGPROC, (LONG)(LONG_PTR)CXWindow::s_BaseWndProc);
    }

    BOOL      bProcessed = FALSE;
    LRESULT   lResult    = NULL;
    CXWindow *pObj       = NULL;

    //Retrieve the pointer
    //pObj = (CXWindow *)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
    pObj = (CXWindow *)::GetWindowLongPtr( hWnd, DWL_DLGPROC);


    //Filter message through child classes
    if (NULL != pObj) {
        lResult = pObj->pWndProc(hWnd, uiMsg, wParam, lParam, &bProcessed);
    }

    if (TRUE == bProcessed) {
        return lResult;
    } else {
        //////If message was unprocessed, send it back to Windows.
        //return ::DefWindowProc(hWnd, uiMsg, wParam, lParam);

        return ::CallWindowProc(DefDlgProc, hWnd, uiMsg, wParam, lParam);
    }
}
//---------------------------------------------------------------------------
/*virtual*/LRESULT CXWindow::pWndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam, PBOOL pbProcessed) {
    /*DEBUG*/XASSERT_RET(NULL != _m_hWnd, NULL);

    //This may be overridden to process messages.
    *pbProcessed = FALSE;

    return NULL;
}
//---------------------------------------------------------------------------



--------------------
PM WWW ICQ Skype Jabber   Вверх
GremlinProg
Дата 30.7.2009, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



так, в приложении пример того, что получилось

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  InheritedDialog.rar 118,57 Kb


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


Эксперт
****


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

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



а теперь в приложении сам проект

Присоединённый файл ( Кол-во скачиваний: 9 )
Присоединённый файл  InheritedDialog.rar 29,65 Kb


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


Эксперт
****


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

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



Цитата(Alca @  30.7.2009,  18:10 Найти цитируемый пост)
_m_WndClass.lpfnWndProc   = NULL/*s_BaseWndProc*/; 

Цитата(Alca @  29.7.2009,  17:54 Найти цитируемый пост)
_m_sClassName(""),


Alca, загляни в проект,
посмотри на его логику,
разбери код,
повторяю, 95-97% от того, что у меня написано - стандартный проект win32
CreateWindow заменен на CreateDialog + небольшие изменения/дополнения в классе окна, процедуре окна и цикле сообщений

Это сообщение отредактировал(а) GremlinProg - 30.7.2009, 16:38


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Цитата

а теперь в приложении сам проект 

Присоединённый файл ( Кол-во скачиваний: 0 ) 
  InheritedDialog.rar 29,65 Kb

Спасибо.
У меня этот проект работает. А вот код, который был чуть выше - нет  smile 
Где я накосячил?

Это сообщение отредактировал(а) Alca - 30.7.2009, 16:41


--------------------
PM WWW ICQ Skype Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

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


 




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


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

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