Modeless, resizeable, property sheet
От: Вепрь  
Дата: 09.03.06 15:28
Оценка:
Доброго всем времени суток.
Цель: создание немодального property sheet с возможностью изменеия размеров.
Как делаю:
// Базовый класс для страниц-закладок
template <WORD t_wDlgTemplateID>
class CModelessPropertyPage: 
    public CPropertyPageImpl<CModelessPropertyPage>, 
    public CDialogResize<CModelessPropertyPage>
{
public:
    enum { IDD = t_wDlgTemplateID };

CModelessPropertyPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL): 
    CPropertyPageImpl<CModelessPropertyPage>(title)
    {
    }
    ~CModelessPropertyPage() { if(m_hWnd) DestroyWindow(); }
    
    BEGIN_MSG_MAP(CModelessPropertyPage)
        MESSAGE_HANDLER(WM_INITDIALOG, OnInitPage)
        CHAIN_MSG_MAP(CPropertyPageImpl<CModelessPropertyPage>)
        CHAIN_MSG_MAP(CDialogResize<CModelessPropertyPage>)
    END_MSG_MAP()
    
    BEGIN_DLGRESIZE_MAP(CModelessPropertyPage)
    END_DLGRESIZE_MAP()
    
    LRESULT OnInitPage(UINT, WPARAM , LPARAM , BOOL& bHandled)
    {
        bHandled = false;
        DlgResize_Init(false, false, WS_CHILD | WS_CLIPCHILDREN);
        return 0;
    }
};

// Базовый класс для sheet
// Сразу замечу, что я убиваю property sheet только при закрытии самого приложения, иначе, 
// я его просто прячу.
class CModelessPropertySheet : 
    public CPropertySheetImpl<CModelessPropertySheet>, 
    public CDialogResize<CModelessPropertySheet>
{
public:
    CModelessPropertySheet(_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL):
        CPropertySheetImpl<CModelessPropertySheet>(title, uStartPage, hWndParent)
    {
        m_fChilded = false;
        m_psh.dwFlags |= PSH_NOAPPLYNOW;
        m_psh.dwFlags |= PSH_NOCONTEXTHELP;
    }
    
    ~CModelessPropertySheet() { if(m_hWnd) DestroyWindow(); }

    virtual HWND Create()
    {
        if(m_hSheet) ShowWindow(SW_SHOW);
        else 
        {
            m_hSheet = CPropertySheetImpl<CModelessPropertySheet>::Create();
            ModifyStyle(0, WS_THICKFRAME);
            DlgResize_Init(true, false, 0);
        }
        ::SetFocus(m_hSheet);
        return m_hSheet;
    }

    BEGIN_MSG_MAP(CModelessPropertySheet)
        MESSAGE_HANDLER(WM_CLOSE, OnClose)
        COMMAND_HANDLER(IDOK, BN_CLICKED, OnHide)
        COMMAND_HANDLER(IDCANCEL, BN_CLICKED, OnHide)
        CHAIN_MSG_MAP(CPropertySheetImpl<CModelessPropertySheet>)
        CHAIN_MSG_MAP(CDialogResize<CModelessPropertySheet>)
    END_MSG_MAP()

    BEGIN_DLGRESIZE_MAP(CModelessPropertySheet)
    END_DLGRESIZE_MAP()
    
    LRESULT OnHide(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
    { 
        return ShowWindow(SW_HIDE); 
    }
    LRESULT OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
    { 
        return ShowWindow(SW_HIDE);
    }

private:
    bool m_fChilded;
    HWND m_hSheet;
};

Сооответственно, я создаю наследников от этих базовых классов, добавлюя закладки, вроде всё работает нормально, но никак не получается изменить размеры окна. В чём тут может быть проблема?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
God grant me the serenity to accept the things I cannot change,
courage to change the things I can,
and wisdom to know the difference. (C) Reinhold Niebuhr
Re: Modeless, resizeable, property sheet
От: Gosha Украина  
Дата: 09.03.06 16:01
Оценка: +1
http://codeproject.com/wtl/ResizProSheetTempl.asp
http://codeproject.com/wtl/wizview.asp
http://codeproject.com/wtl/layout_mgr.asp
http://codeproject.com/wtl/propview.asp
Re[2]: Modeless, resizeable, property sheet
От: Вепрь  
Дата: 09.03.06 16:29
Оценка:
Здравствуйте, Gosha, Вы писали:

G>http://codeproject.com/wtl/ResizProSheetTempl.asp

G>http://codeproject.com/wtl/wizview.asp
G>http://codeproject.com/wtl/layout_mgr.asp
G>http://codeproject.com/wtl/propview.asp

Спасибо, конечно, но я это уже видел. Я не могу найти ошибку в своём коде.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
God grant me the serenity to accept the things I cannot change,
courage to change the things I can,
and wisdom to know the difference. (C) Reinhold Niebuhr
Re[3]: Modeless, resizeable, property sheet
От: Gosha Украина  
Дата: 09.03.06 16:54
Оценка:
Здравствуйте, Вепрь, Вы писали:

G>>http://codeproject.com/wtl/ResizProSheetTempl.asp

G>>http://codeproject.com/wtl/wizview.asp
G>>http://codeproject.com/wtl/layout_mgr.asp
G>>http://codeproject.com/wtl/propview.asp

В>Спасибо, конечно, но я это уже видел. Я не могу найти ошибку в своём коде.


Убирать стиль DS_MODALFRAME пробовал? По крайней мере в трех сорцах по ссылкам вверху такую строчку встречал.
Re[4]: Modeless, resizeable, property sheet
От: Вепрь  
Дата: 09.03.06 17:06
Оценка:
Здравствуйте, Gosha, Вы писали:

G>Убирать стиль DS_MODALFRAME пробовал? По крайней мере в трех сорцах по ссылкам вверху такую строчку встречал.


Попробовал, но никакого эффекта не последовало .
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
God grant me the serenity to accept the things I cannot change,
courage to change the things I can,
and wisdom to know the difference. (C) Reinhold Niebuhr
Re: Modeless, resizeable, property sheet
От: Вепрь  
Дата: 13.03.06 08:32
Оценка:
Здравствуйте, Вепрь, Вы писали:

В>Доброго всем времени суток.


Товарищи, киньте пожалуйста идею по данной проблеме, а то замучился уже с этим property.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
God grant me the serenity to accept the things I cannot change,
courage to change the things I can,
and wisdom to know the difference. (C) Reinhold Niebuhr
Re[2]: Modeless, resizeable, property sheet
От: techMick  
Дата: 14.03.06 15:02
Оценка:
Здравствуйте, Вепрь, Вы писали:

В>Здравствуйте, Вепрь, Вы писали:


В>>Доброго всем времени суток.


В>Товарищи, киньте пожалуйста идею по данной проблеме, а то замучился уже с этим property.


А если поменять местами ?
CHAIN_MSG_MAP(CPropertyPageImpl<CModelessPropertyPage>)
CHAIN_MSG_MAP(CDialogResize<CModelessPropertyPage>)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Modeless, resizeable, property sheet
От: Вепрь  
Дата: 17.03.06 16:51
Оценка:
Здравствуйте, techMick, Вы писали:

M>А если поменять местами ?

M> CHAIN_MSG_MAP(CPropertyPageImpl<CModelessPropertyPage>)
M> CHAIN_MSG_MAP(CDialogResize<CModelessPropertyPage>)

Не, не пробовал и наверно уже не попробую, так как сделал по другому, благодаря одной из ссылок, приведённых Gosh'ей. Чтобы считать данную тему закрытой, выкладываю результат.
Сразу замечу, что всячески приветствуются критика, особенно по методу CModelessPropertySheet::OnSize().

//------------------------------------------------
// Соответственно класс закладок, и базовый класс самой sheet
class CModelessPropertySheet;

#define WM_RESIZEPAGE WM_USER + 111

template <class T, class TBase = CTabCtrl>
class ATL_NO_VTABLE CPropTabCtrlImpl : public CWindowImpl<T, TBase>
{
public:
    BOOL SubclassWindow(HWND hWnd)
    {
        return CWindowImpl<T, TBase>::SubclassWindow(hWnd);
    }

    BEGIN_MSG_MAP(CPropTabCtrlImpl)
        MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged)
    END_MSG_MAP()

    LRESULT OnWindowPosChanged(UINT, WPARAM, LPARAM lParam, BOOL&)
    {
        LPWINDOWPOS lpWP = (LPWINDOWPOS)lParam;
        ::SendMessage(m_hWnd, WM_RESIZEPAGE, 0, lpWP->cx);
        return 0;
    }
};

class CPropTabCtrl : public CPropTabCtrlImpl<CPropTabCtrl>
{ };

class CModelessPropertySheet : 
    public CPropertySheetImpl<CModelessPropertySheet>,
    public CDialogResize<CModelessPropertySheet>
{
public:
    CPropTabCtrl                        m_wPropertyTab;

    CModelessPropertySheet()
    {
        m_psh.dwFlags |= PSH_NOAPPLYNOW;
        m_psh.dwFlags |= PSH_NOCONTEXTHELP;
    }

    ~CModelessPropertySheet()
    {
        if(m_hWnd) DestroyWindow();
    }

    static int CALLBACK PropSheetCallback(HWND hWnd, UINT uMsg, LPARAM lParam)
    {
        if(uMsg == PSCB_PRECREATE)
        {
            LPDLGTEMPLATE lpDT = (LPDLGTEMPLATE)lParam;
            lpDT->style -= DS_MODALFRAME | WS_VISIBLE;
            lpDT->style |= WS_POPUP | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MINIMIZEBOX;
            return 0;
        }
        else return CPropertySheetImpl<CModelessPropertySheet>::PropSheetCallback(hWnd, uMsg, lParam);
    }

    BEGIN_MSG_MAP(CModelessPropertySheet)
        MESSAGE_HANDLER(WM_SIZE, OnSize)
        CHAIN_MSG_MAP(CPropertySheetImpl<CModelessPropertySheet>)
        CHAIN_MSG_MAP(CDialogResize<CModelessPropertySheet>)
    END_MSG_MAP()

    BEGIN_DLGRESIZE_MAP(CModelessPropertySheet)
        DLGRESIZE_CONTROL(ATL_IDC_TAB_CONTROL, DLSZ_SIZE_X | DLSZ_SIZE_Y)
        DLGRESIZE_CONTROL(IDOK, DLSZ_MOVE_X | DLSZ_MOVE_Y)
        DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y)
    END_DLGRESIZE_MAP()

    LRESULT Init(HWND hwndParent)
    {
        ShowWindow(SW_HIDE);
        SetParent(hwndParent);
        ModifyStyle(0, WS_THICKFRAME);
        DlgResize_Init(true, true, WS_THICKFRAME);
        m_wPropertyTab.SubclassWindow(GetTabControl());
        return 0;
    }

    LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        if(m_wPropertyTab != NULL)
        {
            m_wPropertyTab.MoveWindow(7, 7, LOWORD(lParam) - 10, HIWORD(lParam) - 20);
            CWindow wActivePage = GetActivePage();
            if(wActivePage != NULL)
            {
              CRect rect;
              m_wPropertyTab.GetClientRect(&rect);
              m_wPropertyTab.AdjustRect(FALSE, &rect);
                // Вот эта часть была выведена подбором :(, может быть можно это как-то вылечить, а то "кривовато" выглядит
                rect.left += 4;
                rect.right += 5;
                rect.bottom -=15;
                rect.top += 7;

              wActivePage.MoveWindow(rect);
            }
        }
        return CDialogResize<CModelessPropertySheet>::OnSize(uMsg, wParam, lParam, bHandled);
    }
};
//------------------------------------------------
// А вот собственно и сама закладка
class CPage1 :
    public CPropertyPageImpl<CPage1>,
    public CDialogResize<CPage1>
{
public:
    enum { IDD = IDD_PAGE1 };
    CPage1(LPCTSTR lpszTitle = NULL) : CPropertyPageImpl<CMHServerPage>(lpszTitle)
    {
        m_psp.dwFlags |= PSP_USETITLE;
        SetTitle(lpszTitle);
    }

    ~CPage1()
    {
        if(m_hWnd) DestroyWindow();
    }

    BEGIN_MSG_MAP(CPage1)
        MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
        MESSAGE_HANDLER(WM_SIZE, OnSize)
        CHAIN_MSG_MAP(CDialogResize<CPage1>)
        CHAIN_MSG_MAP(CPropertyPageImpl<CPage1>)
    END_MSG_MAP()
    BEGIN_DLGRESIZE_MAP(CPage1)
        DLGRESIZE_CONTROL(IDC_LIST_SERVER, DLSZ_SIZE_X | DLSZ_SIZE_Y)
        DLGRESIZE_CONTROL(IDC_STATIC_HEADER, DLSZ_SIZE_X)
    END_DLGRESIZE_MAP()

    LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
    LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
};

//------------------------------------------------
// Использование
class CMySheet : public CModelessPropertySheet
{
public:
    CMySheet(LPCTSTR lpszTitle)
    {
        m_page1.SetTitle(L"Page1");
        m_page2.SetTitle(L"Page2");
        AddPage(m_page1);
        AddPage(m_page2);
        SetActivePage(0);
    }
    BEGIN_MSG_MAP(CMySheet)
        CHAIN_MSG_MAP(CModelessPropertySheet)
    END_MSG_MAP()
    virtual LRESULT Init(HWND hwndParent)
    {
        CModelessPropertySheet::Init(hwndParent);
        //SetIcon(hIcon, TRUE);
        return 0;
    }
private:
    CPage1                            m_page1;
    CPage2                            m_page2;
};

//............

CMySheet sheet;
sheet.Create(::GetActiveWindow());
sheet.SetTitle(CAutoStr()(IDS_HEALTH_MONITOR));
sheet.Init(hWnd);
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
God grant me the serenity to accept the things I cannot change,
courage to change the things I can,
and wisdom to know the difference. (C) Reinhold Niebuhr
Re[5]: Modeless, resizeable, property sheet
От: Boss Россия http://alex-boss.narod.ru
Дата: 17.03.06 20:08
Оценка:
Здравствуйте, Вепрь, Вы писали:

В>Здравствуйте, Gosha, Вы писали:


G>>Убирать стиль DS_MODALFRAME пробовал? По крайней мере в трех сорцах по ссылкам вверху такую строчку встречал.


В>Попробовал, но никакого эффекта не последовало .


У меня сделано приблизительно вот так:

template <class T, class TBase = CPropertySheetWindow, class baseSheet = CPropertySheetImpl<T, TBase> >
class CResizablePropertySheetImpl :
public baseSheet,
....
{
....
static int CALLBACK PropSheetCallback(HWND hWnd, UINT uMsg, LPARAM lParam)
{
if(uMsg == PSCB_PRECREATE)
{
int nResult = baseClass::PropSheetCallback(hWnd, uMsg, lParam);
T* pT = (T*)ATL::_AtlWinModule.ExtractCreateWndData();
ATL::_AtlWinModule.AddCreateWndData(&pT->m_thunk.cd, pT);

DLGTEMPLATE* dlg = (DLGTEMPLATE*) lParam;
dlg->style &= ~(DS_MODALFRAME);
dlg->style |= (WS_THICKFRAME);
return nResult;
}
return = baseClass::PropSheetCallback(hWnd, uMsg, lParam);
}
...............
}
... << RSDN@Home 1.2.0 alpha rev. 648>>
Re[5]: Modeless, resizeable, property sheet
От: Boss Россия http://alex-boss.narod.ru
Дата: 17.03.06 20:43
Оценка:
Здравствуйте, Вепрь, Вы писали:

В>Здравствуйте, Gosha, Вы писали:


G>>Убирать стиль DS_MODALFRAME пробовал? По крайней мере в трех сорцах по ссылкам вверху такую строчку встречал.


В>Попробовал, но никакого эффекта не последовало .


У меня сделано приблизительно вот так:

template <class T, class TBase = CPropertySheetWindow, class baseSheet = CPropertySheetImpl<T, TBase> >
class CResizablePropertySheetImpl :
public baseSheet,
....
{
....
static int CALLBACK PropSheetCallback(HWND hWnd, UINT uMsg, LPARAM lParam)
{
if(uMsg == PSCB_PRECREATE)
{
int nResult = baseClass::PropSheetCallback(hWnd, uMsg, lParam);
T* pT = (T*)ATL::_AtlWinModule.ExtractCreateWndData();
ATL::_AtlWinModule.AddCreateWndData(&pT->m_thunk.cd, pT);

DLGTEMPLATE* dlg = (DLGTEMPLATE*) lParam;
dlg->style &= ~(DS_MODALFRAME);
dlg->style |= (WS_THICKFRAME);
return nResult;
}
return = baseClass::PropSheetCallback(hWnd, uMsg, lParam);
}
...............
}
... << RSDN@Home 1.2.0 alpha rev. 648>>
Re[4]: Modeless, resizeable, property sheet
От: Константин Ленин  
Дата: 19.03.06 10:39
Оценка:
Здравствуйте, Вепрь, Вы писали:

В> LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)

В> {
В> if(m_wPropertyTab != NULL)
В> {
В> m_wPropertyTab.MoveWindow(7, 7, LOWORD(lParam) — 10, HIWORD(lParam) — 20);
В> CWindow wActivePage = GetActivePage();
В> if(wActivePage != NULL)
В> {
В> CRect rect;
В> m_wPropertyTab.GetClientRect(&rect);
В> m_wPropertyTab.AdjustRect(FALSE, &rect);
В> // Вот эта часть была выведена подбором , может быть можно это как-то вылечить, а то "кривовато" выглядит
В> rect.left += 4;
В> rect.right += 5;
В> rect.bottom -=15;
В> rect.top += 7;

В> wActivePage.MoveWindow(rect);

В> }
В> }
В> return CDialogResize<CModelessPropertySheet>::OnSize(uMsg, wParam, lParam, bHandled);
В> }
В>};

Это, по-моему, и то кривее
Re[5]: Modeless, resizeable, property sheet
От: Вепрь  
Дата: 20.03.06 08:19
Оценка:
Здравствуйте, Константин Ленин, Вы писали:

В>> if(wActivePage != NULL)

КЛ>Это, по-моему, и то кривее

Хотелось бы знать причину, или Вы имеете ввиду, что-то типа этого:
if(wActivePage) {...}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
God grant me the serenity to accept the things I cannot change,
courage to change the things I can,
and wisdom to know the difference. (C) Reinhold Niebuhr
Re[6]: Modeless, resizeable, property sheet
От: Константин Ленин  
Дата: 20.03.06 08:45
Оценка:
Здравствуйте, Вепрь, Вы писали:

В>Здравствуйте, Константин Ленин, Вы писали:


В>>> if(wActivePage != NULL)

КЛ>>Это, по-моему, и то кривее

В>Хотелось бы знать причину, или Вы имеете ввиду, что-то типа этого:

В>
В>if(wActivePage) {...}
В>


по-моему правильнее IsWindow()
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.