Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Создать динамически окно(контрол) и привязать к нему обработчик  (Прочитано 57791 раз)
0 Пользователей и 8 Гостей смотрят эту тему.
Boriska
Помогающий

us
Offline Offline

« : 13-07-2015 08:59 » 

Привет форумчане.

Подскажите пожалуйста. МFC.
Контруктор -> Нарисовал окно(контрол) ->Подцепил через визард к переменной -> Прописалось в карте сообщений
или прописал скажем ручками. Тут все понятно.
А вот как если создал окно(контрол) динамически подвязать его к обработчику ?
« Последнее редактирование: 13-07-2015 09:49 от Boriska » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 13-07-2015 12:00 » 

Аналогично, через однозначный ID, который передаётся в ф-ю Create.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #2 : 13-07-2015 12:14 » 

да, но тут вроде нет входного указателя на функцию обработчик

Код: (C++)
CWnd
virtual BOOL Create(
   LPCTSTR lpszClassName,
   LPCTSTR lpszWindowName,
   DWORD dwStyle,
   Const RECT& rect,
   CWnd* pParentWnd,
   UINT nID,
   CCreateContext* pContext = NULL
);

HWND WINAPI CreateWindow(
  _In_opt_ LPCTSTR   lpClassName,
  _In_opt_ LPCTSTR   lpWindowName,
  _In_     DWORD     dwStyle,
  _In_     int       x,
  _In_     int       y,
  _In_     int       nWidth,
  _In_     int       nHeight,
  _In_opt_ HWND      hWndParent,
  _In_opt_ HMENU     hMenu,
  _In_opt_ HINSTANCE hInstance,
  _In_opt_ LPVOID    lpParam
);
« Последнее редактирование: 13-07-2015 12:56 от Boriska » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 14-07-2015 09:04 » 

да, но тут вроде нет входного указателя на функцию обработчик

О как! А разве в варианте
->Подцепил через визард к переменной -> Прописалось в карте сообщений ...
он есть?  Быть такого не может  А черт его знает...  Ага

Всё работает через карту сообщений. Для этого служит вот это параметр (аргумент)
   ...
   UINT nID,
   ...
, который и является связующим звеном. Поэтому ОООЧЕНЬ важно, чтобы его значение было однозначным для данной формы (диалога).

А дальше используем вариант "или" из
Прописалось в карте сообщений или прописал скажем ручками.

Даже!!! Если это один из стандартных контролов (например CEdit), то можно запросто использовать "родные" ф-ции обработки стандартных сообщений контрола.

что-то типа

дано

#define IDC_MY_EDIT 123
CEdit m_wndMyEdit;
m_wndMyEdit.Create(..., IDC_MY_EDIT, ...);

тогда можно добавить в карту

ON_EN_CHANGE(IDC_MY_EDIT, &CMyDlg::OnEnChangeMyEdit)

void CMyDlg::OnEnChangeMyEdit()
{
   ...
}
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #4 : 14-07-2015 11:58 » 

Спасибо. Но Вы наверное не совсем поняли, что я хочу. В ваших объяснениях присутствует
Код: (C++)
#define IDC_MY_EDIT 123
ON_EN_CHANGE(IDC_MY_EDIT, &CMyDlg::OnEnChangeMyEdit)

это предполагает что до этапа компиляции я выберу константы, опять же ручками добавлю
макрос в карту.
А мне хочется накропать нечто вроде редактора. Зашел в режим Add добавил контролы и они должны
быть увязаны на обработчик(и). Потом режим  Add выключил и программа должна будет в следующие
разы запускаться с добавленными контролами. Аналогично и Remove.
Я же в этом случае не могу добавить запись в карту, и не могу константы выбрать.
Записан
darkelf
Молодой специалист

de
Offline Offline

« Ответ #5 : 14-07-2015 12:24 » 

Boriska, посмотрите, как это делают, например, Qt или GTK. Оба они позволяют динамически добавлять кнопочки на форму, в смысле программно, хоть 100 штук. И у обоих у них есть редакторы, которые позволяют вообще описывать форму в каком-то формате, сохраняемом в файл, и подгружать её потом из файла динамически.
Записан
Boriska
Помогающий

us
Offline Offline

« Ответ #6 : 14-07-2015 13:02 » 

Хорошо бы, но с Qt GTK не знаком вообще. А нужно на MFC
Записан
darkelf
Молодой специалист

de
Offline Offline

« Ответ #7 : 14-07-2015 13:30 » 

Я имею в виду подход, хотя ,конечно, там объём кода довольно большой и разобраться может оказаться непросто.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #8 : 14-07-2015 15:26 » 

Boriska, нуууу как вопрос был задан... Сорри, телепатия на нуле.

ON_EN_CHANGE я привёл в качестве примера стд. контрола. Вы же не уточнили, какие именно контролы вы собираетесь использовать.

нууу начнём с того, что нет под Виндой другого Бога, кроме Win API, а MFC, .NET, ГТК, ОТК, ИТД и иже с ними лишь жалкие оболочки. При этом MFC одна из самых "низких". Таким образом, если что-то и делается "динамически" со стандартными Диалогами и Контролами винды, то это лишь видимость.

Посмотрите, как это делается, например со Списком последних файлов (меню). Точно также резервируются ID, а потом просто некоторые из них используются. И никакого шаманства. А для динамических контролов можно даже задать дипазон ID (ключевое слово RANGE см. в MSDN)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #9 : 15-07-2015 09:02 » 

Да кстати насчет
Цитата
UINT nID,
, который и является связующим звеном. Поэтому ОООЧЕНЬ важно, чтобы его значение было однозначным для данной формы (диалога).
Лазил в Resource.h какие то нелады были, добавлял при копировании ресурсов какие то ID, так там все ID идут секциями. Секция ID диалогов
секция контролов....и номера просто в порядке увеличения. Я там не видел IDхи чисто одного диалоги, потом другого. Можно по подробнее.

Я так полагаю мне надо разобраться с EnumChildWindows, каким то образом получать(пока не понял) получать HWND дочерних окон ->int WINAPI GetDlgCtrlID(_In_ HWND hwndCtl); добраться до максимального и криэйтить окна с id = max+1 ?
Записан
Boriska
Помогающий

us
Offline Offline

« Ответ #10 : 15-07-2015 11:05 » 

Вот нашел для поиска id такое решение, проблема не возвращает кода и текста кнопки ОК
Код: (C++)
void func()
{
        CWnd*  pwnd;
        CString  m_str;
        CString  wndtext;
        int          ctrlId;

        pwnd = this->GetWindow(GW_CHILD);
        pwnd->GetWindowText(m_str);


        for (int j = 1; j < this->GetWindowedChildCount(); j++)
        {
                pwnd = pwnd->GetWindow(GW_HWNDNEXT);
                pwnd->GetWindowTextW(wndtext);
                ctrlId = pwnd->GetDlgCtrlID();
                CMessage dlg;
                dlg.m_text.Format( L"Wnd Text = %s ctrlId = %d", wndtext, ctrlId);
                dlg.DoModal();
        };
}
Записан
Boriska
Помогающий

us
Offline Offline

« Ответ #11 : 16-07-2015 13:29 » 

Победил создание окон. Остались ДрагиДропы.Спасибо за наводки.

Объявил две константы
Код: (C++)
ON_COMMAND_RANGE(DYN_CTRL_ID_MIN, DYN_CTRL_ID_MAX, func
и сделал переменную последнего созданого контрола. Все работает.
Но возник вопрос. Окна у меня в тестовом примере разместились черепицей. И при клике
на окно которое сверху почему то приходит сообщение от окна лежащего в самом низу.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 18-07-2015 12:03 » 

Boriska, дык... Однозначно могу сказать только одно, тестовый пример не выполняет поставленные ему задачи.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #13 : 19-07-2015 19:31 » 

Из ЛС.

Бориска, чесслово, ну как тут не заматериться. Как можно помочь исключительно ДОГАДЫВАЯСЬ о том ЧТО и КАК сделано? И, если на первое сообщение ещё можно было хоть как-то дать общие советы, то теперь... Сорри, но не видя ЧТО и КАК сделано... А телепатия по такой жаре на нуле.
 

Жара. Сижу на даче Улыбаюсь
Ну короче я пошел по такому пути

Код: (C++)
#define         DYN_CTRL_ID_MIN                 5000
#define         DYN_CTRL_ID_MAX                 5500

ON_COMMAND_RANGE(DYN_CTRL_ID_MIN, DYN_CTRL_ID_MAX, &CDynWndCreateDlg::OnClickDynamicWnd)

// в инит диалоге
        m_currCtrlID = DYN_CTRL_ID_MIN;
        m_rect = CRect(5, 5, 140, 140);
        m_bmNormalTank.LoadBitmap(IDB_N_TANK);
        m_ctrlVec = GetCtrlsAllocs(L"MyWnd"); // беру из базы расположения

//добавляю окна-контролы так
BOOL CDynWndCreateDlg::AddNewControl()
{
        CWnd *pWnd = NULL;
        pWnd = new CStatic();
        BOOL result = FALSE;

        if (m_currCtrlID < DYN_CTRL_ID_MAX)
        {
                pWnd->Create(L"Static", L"Tank", WS_BORDER | WS_CHILD | WS_VISIBLE |    SS_BITMAP | SS_NOTIFY,
                        m_rect, this, m_currCtrlID);

                ((CStatic*)(pWnd))->SetBitmap(m_bmNormalTank);
                CCtrlParams pnt(m_rect);
                AddControl(L"Tank", m_currCtrlID, pnt);
                m_currCtrlID++;

                m_rect.left += 20;
                m_rect.top += 20;
                m_rect.right += 200;
                m_rect.bottom += 20;

                result = TRUE;
        }
       
        return result;
}

//смотрю на клик вот так

void CDynWndCreateDlg::OnClickDynamicWnd(UINT nID)
{
        CMessage dlg;
        CString text;
        GetDlgItem(nID)->GetWindowText(text);
        dlg.m_text.Format(L"Wnd Text = %s ctrlId = %d", text, nID);
        dlg.DoModal();
}
 


+ Я так понимаю, Вы начинающий в MFC, поэтому почитайте перевод статьи Блуждания по лабиринту маршрутизации сообщений и команд в MFC на RSDN

+ Всё-таки, наверное, придётся описать словами, что Вы хотите получить, ибо, сорри, но приведённые обрывки исходников этого не демонстрируют.

+ к предыдущему пункту, какие именно сообщения Вы собираетесь отлавливать, или что должен делать контрол по клику?
« Последнее редактирование: 19-07-2015 19:34 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #14 : 19-07-2015 20:17 » 

Цитата
+ Всё-таки, наверное, придётся описать словами, что Вы хотите получить, ибо, сорри, но приведённые обрывки исходников этого не демонстрируют.

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

Цитата
к предыдущему пункту, какие именно сообщения Вы собираетесь отлавливать, или что должен делать контрол по клику?
Ну в режиме работы я полагаю должен ловить левый клик, а режиме редактирования по идее (button down, button up,
ну и наверное move)

Блуждания читал как-то, но понял далеко не все, попробую еще.

Добавлено через 13 часов, 32 минуты и 4 секунды:
Вот что у меня получается.

Создаю по кнопке и и при перезапуске приложения восстанавливаю из базы.
Но остался вопрос с сообщением от перекрывающихся окон. Если они не перекрываются то все по клику
на каждом окне получаю то, что ожидал - те сообщение с его ID, а если перекрываются получаю ID
самого нижнего окна. Жаль

* Tect.png (31.26 Кб - загружено 2190 раз.)
« Последнее редактирование: 20-07-2015 11:55 от Джон » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #15 : 20-07-2015 13:30 » 

Да вроде всё нормально работает.


* ss1.gif (26.72 Кб - загружено 1796 раз.)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #16 : 20-07-2015 13:46 » 

А кде кликаете ?
Если я кликаю в красной области то получу сообщение что кликнул
на wnd id =5000
Если на зеленых областях то получу Id того окна на котором кликнул
Если на синей области то получуу Id = 5004 | 5005 | 5006 в зависимости
от того места области где кликну


* Tect2.png (43.39 Кб - загружено 1959 раз.)
« Последнее редактирование: 22-07-2015 10:43 от Джон » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #17 : 22-07-2015 11:04 » 

Ну и что тут удивительного? Всё абсолютно правильно и логично. Существует определённый порядок распложения окон (т.н. Z-Order). Изначально это порядок создания окон. В Вашем случае это:

5000
5001
5002
5003
5004
5005
5006
5007

Когда Вы кликаете ГДЕ-ТО на форме, производится поиск окна, в прямоугольной области которого был произведён клик (т.н. HitTest).
Ессно, что первым откликается окно, находящееся в начале списка. Например, для синей области это 5004 5005 5006 и только совсем немного внизу 5007.



Отрисовка окон производится в этом же порядке, поэтому следующее окно находится поверх предыдущего.

* Tect2 2.png (43.45 Кб - загружено 1809 раз.)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #18 : 22-07-2015 13:40 » 

То бишь ловить через ON_COMMAND_RANGE не выйдет ? так как он не учитывает Z порядок
и возвращает ID первого в списке окна ?

Дочитался до PreTranslateMessage. Там возвращается структура сообщения. Но как по ней
определить кого таки кликнули не понял.(ну в смысле если они перекрываются).

Кстати эксперимент показал что так работают все контролы когда они перекрыты. Значит
должен быть способ определять какое окно в этом порядке было кликнуто с поледующим
вытягиванием всех его атрибутов.

Джон а где мона толково это почитать?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #19 : 22-07-2015 14:05 » 

То бишь ловить через ON_COMMAND_RANGE не выйдет ? так как он не учитывает Z порядок
и возвращает ID первого в списке окна ?

Нет, ON_COMMAND_RANGE остаётся как есть. Этот обработчик отлавливает сообщения независимо от порядка их отправителей. Если от него отказаться, то надо будет изначально внести в карту N ON_COMMAND, где N - максимально разрешённое количество окон. В Вашем случае исходя из

Код: (C++)
#define         DYN_CTRL_ID_MIN                 5000
#define         DYN_CTRL_ID_MAX                 5500

N=501. Хотите? Ага

По этим же соображениям PreTranslateMessage тоже не поможет.

Цитата
Кстати эксперимент показал что так работают все контролы когда они перекрыты.

Улыбаюсь (см. ниже)

Цитата
Значит должен быть способ определять какое окно в этом порядке было кликнуто с поледующим
вытягиванием всех его атрибутов.

Нууу, можете предложить свой. Ага На самом деле всё очень просто.
Как бы Вы реализовали подобную логику? Например, для графического редактора. Есть список элементов (прямоугольников), скажем 20 штук, все они имеют одинаковый размер и находятся точно один под другим. Надо выбрать.
Или, для примера, уже упомянутый редактор ресурсов Студии. В случае, если, например, все кнопки расположены (по нелепой случайности автоформатирования, автоцентрирования и тп) одна под другой.

Цитата
Джон а где мона толково это почитать?

Про что про "ЭТО"? Создание алгоритмов? Здесь проблема не системы, а архитектуры, рабочей модели. Т.е. сначала она решается с помощью нарезаных бумажек и пальца.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #20 : 27-07-2015 14:26 » 

Привет
Цитата
Про что про "ЭТО"?
"Это" про то как, окна организованы(иерархии), как маршрутизацию команд (mfc) (статья про блуждание - это же так, отсебятина Улыбаюсь, ну чтобы основательно разобраться)

вот наваял, возвращает ID (нужного(верхнего)"правильного") кликнутого контрола.
Цитата
int CWndHitTest::GetControlID(POINT scrPntClck)
{
   CWnd*   pWnd;
   CRect   wndrect;

   std::vector <HWND> wndsVect;

   HWND      hWnd = ::WindowFromPoint(scrPntClck);
   while (hWnd)
   {
      pWnd = CWnd::FromHandle(hWnd);
      pWnd->GetWindowRect(wndrect);

      if (wndrect.PtInRect(scrPntClck))
      wndsVect.push_back(hWnd);

      hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
   }

   if (wndsVect.empty())
      return 0;

   hWnd = wndsVect[wndsVect.size()-1];
   
   pWnd = CWnd::FromHandle(hWnd);
   return pWnd->GetDlgCtrlID();
}
« Последнее редактирование: 28-07-2015 06:18 от Boriska » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #21 : 28-07-2015 09:46 » 

статья про блуждание - это же так, отсебятина Улыбаюсь,

Хм... даже как-то раньше не задумывался... "Но если так, без умиления взглянуть" (с), а не всё ли в этом мире "отсебятина"? Лично мне, в своё время, отсебятины корифеев, как например Paul DiLascia, очень помогли. Но Вы абсолютно правы, отсебятина остаётся отсебятиной, поэтому в этом случае могу порекомендовать справочник MSDN. Говорят, там есть АБСОЛЮТНО ВСЁ.
« Последнее редактирование: 28-07-2015 10:06 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #22 : 28-07-2015 12:11 » 

Привет.

  Ну лады. Про отсебятину наверное перебор. Просто считаю, любая подаваемая информация информация, что бы принята была, необходимо обеспечить условия с двух сторон. Представьте ситуацию, Microsoft выпускает библиотеку, MSDN и подобную статью. И на завтра все создают супер-пупер приложения. Не получиться.
  Или они библиотеку для себя сделали?, а мы смертные, должны как куры сорные, рыться в поисках обломков кода в этой мусорке по прозвищу Сеть. (вот кстати про то, что сообщения будут пролетать через стопку окон, в этой статье от Paul DiLascia не заметил)

Джон вы как-то обмолвились
Цитата
Поэтому ОООЧЕНЬ важно, чтобы его значение было однозначным для данной формы (диалога).
Можете это прокомментировать? Мы когда перетягиваем элементы с тулбара на диалоги, система(studio) просто присваивает ему ++ID и кладет по порядку в (я так понял) секцию контролов (IDC_xx). И нет там вроде никаких IDC_for somebody.

Это типа если у меня какой то диалог создает на других диалогах элементы(окна), то мне следить за последним(наибольшим?) номером созданного элементы(окна) для каждого диалога ?
« Последнее редактирование: 28-07-2015 13:14 от Boriska » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #23 : 29-07-2015 11:20 » 

Или они библиотеку для себя сделали?, а мы смертные, должны как куры сорные, рыться в поисках обломков кода в этой мусорке по прозвищу Сеть.

Ну так в этом аспекте особенно ценны "отсебятины" людей (типа Paul DiLascia), которые уже "порылись", разобрались в чём-то, понаступали на грабли, потом результаты (опыт) разжевали и положили в "рот".

Цитата
Джон вы как-то обмолвились
Цитата
Поэтому ОООЧЕНЬ важно, чтобы его значение было однозначным для данной формы (диалога).
Можете это прокомментировать? Мы когда перетягиваем элементы с тулбара на диалоги, система(studio) просто присваивает ему ++ID и кладет по порядку в (я так понял) секцию контролов (IDC_xx). И нет там вроде никаких IDC_for somebody.

Проблема заключается в том, что наличие на одной форме (диалог) контролов с одинковыми ID недопустимо, ибо именно через них осуществляется доступ к этому самому контролу.

Цитата
Это типа если у меня какой то диалог создает на других диалогах элементы(окна), то мне следить за последним(наибольшим?) номером созданного элементы(окна) для каждого диалога ?

Вы можете посмотреть в файле resource.h, как этим, например, управляет редактор ресурсов Студии. Там в самом низу есть такой (или похожий, зависит от версии Студии) блок:

Код: (C++)
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        958
#define _APS_NEXT_COMMAND_VALUE         33801
#define _APS_NEXT_CONTROL_VALUE         1964
#define _APS_NEXT_SYMED_VALUE           117
#endif

В Вашем случае, когда АБСОЛЮТНО ВСЕ (если я правильно понял) элементы будут создаваться динамически, Вы можете сами взять на себя управление След. Свободным ID (например Ваше ++ID). Если же некоторые контролы присутствуют изначально (были созданы в редакторе Студии), то вы можете зарезервировать диапазон "с запасом" и лежащий "далеко" за пределами, например, _APS_NEXT_CONTROL_VALUE.

Ещё раз, речь об уникальности идёт только в пределах одной формы (родителя).
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #24 : 31-07-2015 10:58 » new

Привет.

Тык. Окна создаю, клики обрабатываю вроде все получилось (спсб). Теперь надо поместить на окно битмапу.
Добавил красным.

Не фурычит. SetBitmap возвращает 0, битмапа вернула 1 -> удачно загрузилась. Полный код.

BOOL CWndControl::AddNewControl(CWnd* pParentWnd, int ctrlMaxID, CCtrlParams ctrlParams)
{
   CWnd *pWnd = NULL;
   pWnd = new CStatic();
   BOOL result = FALSE;
   CBitmap bmp;
   bmp.LoadBitmap(ctrlParams.GetCtrlId());


   if (ctrlParams.GetCtrlId() < ctrlMaxID)
   {
      result = pWnd->Create(
         ctrlParams.GetCtrlClass(),
         ctrlParams.GetCtrlCaption(),
         WS_BORDER | WS_CAPTION | WS_VISIBLE | SS_BITMAP | SS_CENTERIMAGE | SS_NOTIFY,
         ctrlParams.GetCtrlRect(),
         pParentWnd,
         ctrlParams.GetCtrlId()
         );

      ((CStatic*)(pWnd))->SetBitmap(bmp);
   }
   return result;
}
« Последнее редактирование: 31-07-2015 11:30 от Boriska » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #25 : 31-07-2015 13:35 » 

Ну начнём с того, что Вы хотите сделать? Чтобы на контроле ВСЁ время его существования показывалась картинка?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #26 : 31-07-2015 13:52 » 

Я не совсем понял, что значит ВСЕ и НЕ ВСЕ время. Ну как я понимаю битмап должен показываться то время пока окно видно.
О кажись потусторонние силы подсказывают, что битмап по выходу из функции разрушается, ток рационального объяснения для себя не нахожу зачем ему существовать после того как приатачили.
« Последнее редактирование: 31-07-2015 13:58 от Boriska » Записан
darkelf
Молодой специалист

de
Offline Offline

« Ответ #27 : 31-07-2015 15:07 » 

О кажись потусторонние силы подсказывают, что битмап по выходу из функции разрушается, ток рационального объяснения для себя не нахожу зачем ему существовать после того как приатачили.
Ну, например в функции SetBitmap(), не делают полную копию объекта CBitmat, а записывают ссылку на него, или, например HANDLE какого-то системного объекта. Соответственно после выхода из Вашей функции, этот внутренний указатель или HANDLE указывает в никуда, т.к. вызвался деструктор, который освободил память или закрыл HANDLE. Если Вам надо создавать его динамически - ну и создайте его через new в куче, а не как сейчас, на стеке.

А почему так может быть - думаю, когда разрабатывали WinAPI и MFC, память была не таким дешевым ресурсом как сейчас, и её пытались экономить.
« Последнее редактирование: 31-07-2015 15:51 от darkelf » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #28 : 31-07-2015 15:24 » 

О кажись потусторонние силы подсказывают, что битмап по выходу из функции разрушается

И это очень хорошо.  Класс!

ток рационального объяснения для себя не нахожу зачем ему существовать после того как приатачили.

А вот это плохо.  Жаль
Матчасть учить таки придётся. Какой параметр получает SetBitmap? Что такое HBITMAP? Ну а дальше всё просто. Ага

например HANDLE какого-то системного объекта.

Почти угадал. Класс! Только не какого-то системного объекта, а именно HANDLE  этого битмапа.


Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Boriska
Помогающий

us
Offline Offline

« Ответ #29 : 31-07-2015 19:50 » 

Привет
Цитата
Матчасть учить таки придётся. Какой параметр получает SetBitmap? Что такое HBITMAP? Ну а дальше всё просто.
Матчасть бы лучше понимать, тогда учить не приходится  Улыбаюсь Мои знания конечно ну очень далеки от .....Ну насколько знаю HANDLE - адрес на объект создаваемый в системе обычно какой нибудь функцией типа CreateXXX. HBITMAP - полагаю особым от него не отличается, только и того чтобы для проверки типа (чтобы левый хэндл туда не совали).
Согласно msdn SetBitmap принимает хэндл, а я туда сунул CBitmap - интересно че это он не заругался?
Но если бы каким то образом добыл хэндл (каким?), то все одно хэндл умер бы согласно этого кода, так ?
Записан
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines