Доброго Времени суток!
У меня такая проблема:
1) я пишу простой COM-модуль (не ActiveX) и у меня возникла необходимость небольшого диалога с пользователем во-время работы модуля.
2) я вставил "Новый ATL-объекит" Dialog из раздела Miscellaneous. Вместе с ним в ресурсах появился шаблон диалога, в котором я могу создавать элементы управления (мне нужны только кнопки).
Только вот вся загвоздка именно в том, что колличество кнопок (от двух, до двадцати) становиться извесным ТОЛЬКО на стадии работы программы. Следовательно, я должен создавать их динамически!!! А как ??? и как ловить события нажатия на кнопку???
Буду благодарен, в том числе, за ссылочки и кусочки кода.
14.01.03 21:42: Перенесено модератором из 'COM/DCOM/ActiveX' в ATL/WTL — ХД
Здравствуйте, Fir, Вы писали:
Fir>Доброго Времени суток!
Fir>Буду благодарен, в том числе, за ссылочки и кусочки кода.
Было интересно самому такое реализовать, так что время, потраченное на создание этого небольшого кода мне тоже было полезно. Вот кусок кода
#include "resource.h" // main symbols
const UINT MAX_ITEMS = 10;
// IDC_ZERO has been defined in "resource.h"
/////////////////////////////////////////////////////////////////////////////
// CCTPaneWindow
class CCTPaneWindow :
public CAxDialogImpl<CCTPaneWindow>
{
public:
UINT m_lastAdded;
CCTPaneWindow()
:
m_lastAdded(0)
{
}
~CCTPaneWindow()
{
}
enum { IDD = IDD_CTPANEWINDOW };
BEGIN_MSG_MAP(CCTPaneWindow)
//BEGIN_MSG_MAP_EX(CCTPaneWindow)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
COMMAND_RANGE_HANDLER((IDC_ZERO+1), (IDC_ZERO+m_lastAdded), OnClickedAddedButton)
COMMAND_HANDLER(IDC_ADD, BN_CLICKED, OnClickedAdd)
END_MSG_MAP()
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return 1; // Let the system set the focus
}
LRESULT OnClickedAddedButton(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
CString report;
report.Format("Вы пресснули на батон, который у нас за номером \'%i\'", wID - IDC_ZERO);
MessageBox(report, "Здесь могла быть Ваша реклама (тел. (033) 03-03-03)");
// делаем что-то более полезное
return 0;
}
LRESULT OnClickedAdd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
// TODO : Add Code for control notification handler.
m_lastAdded++;
if(m_lastAdded > MAX_ITEMS){
// Больше не надо! Надоело...
MessageBox("Достигли максимального количества баттонов", "Нутро");
return 0;
}
CWindow add_button = GetDlgItem(IDC_ADD);
// для того, чтобы посмотреть размеры этого кантрола (чтобы без заморочек)
// Прыгаем с бубном вокруг костра, сыпем травы в огонь для благовония...
// Все для того, чтобы баттоны были ровно друг под другом
CRect main_rect;
GetWindowRect(main_rect);
CRect button_rect;
add_button.GetWindowRect(button_rect);
button_rect.OffsetRect(-main_rect.left, -main_rect.top);
int height = button_rect.Height();
button_rect.OffsetRect(0, (height + 3) * m_lastAdded);
CString caption;
caption.Format("Батон #%i", m_lastAdded);
CButton new_button;
new_button.Create(m_hWnd, button_rect, caption,
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
BS_PUSHBUTTON | WS_TABSTOP | WS_VISIBLE | BS_FLAT);
new_button.SetDlgCtrlID(IDC_ZERO + m_lastAdded);
// Дефолтный фонт никогда еще никого не радовал
HFONT own_font = GetFont();
new_button.SetFont(own_font);
return 0;
}
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// TODO : Add Code for message handler. Call DefWindowProc if necessary.
for(int i = 1; i <= MAX_ITEMS;i++){
CWindow btn = GetDlgItem(IDC_ZERO + i);
if(btn.IsWindow())
btn.DestroyWindow();
}
return 0;
}
};
Немного о примере. Это небольшой плагин к Эксплореру, если нужно, могу выслать проект.
Если пользуешь VC 6.0, то обязательно скачай WTL 7.0, а то будут проблемы с загрузкой ресурсов.
Народу не нужны нездоровые сенсации. Народу нужны здоровые сенсации! (с) Стругацкие.
Здравствуйте, Dwarf!
Спасибо, но я зделал по другому!
Без ограничения максимального числа кнопок!
Но всё равно спасибо.