Kultura
Помогающий
Offline
|
|
« : 25-11-2009 19:06 » |
|
Наверное, сразу нужно уточнить, что пользуюсь vs 2008 express, в которой отсутствует MFC. Ну а мой вопрос в том, если обобщая, как правильно разместить окошко диалога в классе. Ведь процедура окна в классе должна быть объявлена статической, значит и используемые в ней переменные тоже. В связи с этим, возникают проблемы. Вот конкретный пример: пользовательское окошко подсказки (tooltip). -- В конструкторе m_hWndToolTip = CreateWindow (), диалоговая процедура TTDlgProc (). -- static vector<ETOOLINFO>vTools; - массив структур добавленных инструментов, содержащий и оригинальные процедуры этих интрументов. -- SubclassProc () - субклассинг, эта процедура использует информацию из vTools (оригинальные процедуры инструментов под субклассингом), указатель m_hWndToolTip и т.д. class EncToolTip { ...
// Tooltip window: private: static HWND m_hWndToolTip; static HWND m_hWndTTStatic; private: static LRESULT CALLBACK TTDlgProc (HWND, UINT, WPARAM, LPARAM);
// Tools: private: static vector<ETOOLINFO>vTools; // Массив структур static ETTADATA adata; // Структура вспомогательных данных private: static LRESULT CALLBACK SubclassProc (HWND, UINT, WPARAM, LPARAM);
... };
Ну так вот, все прекрасно работает, пока не пытаешься создать второй экземпляр данного класса Подскажите, пожалуйста, как сделать правильно. Использую express постоянно, все время возникает желание организовать контролы в иерархию. Может быть такое уже релизовано?
|
|
« Последнее редактирование: 25-11-2009 19:13 от Kultura »
|
Записан
|
|
|
|
Вад
|
|
« Ответ #1 : 25-11-2009 19:46 » |
|
Зачем у тебя все поля класса статические? Чтобы нормально создавать второй экземпляр класса, у каждого объекта должны быть персональные данные. А static - это данные класса, а не объекта. То есть, доступны всем объектам сразу.
|
|
|
Записан
|
|
|
|
Kultura
Помогающий
Offline
|
|
« Ответ #2 : 26-11-2009 13:31 » |
|
Зачем у тебя все поля класса статические? Чтобы нормально создавать второй экземпляр класса, у каждого объекта должны быть персональные данные. А static - это данные класса, а не объекта. То есть, доступны всем объектам сразу.
Потому что диалоговые процедуры статические. А этого, если не ошибаюсь, требуют функции вроде CreateDialog (). Т.е. те, которым нужен указатель на DLGPROC. При этом ф-ия - член класса должна объявляться статической или быть глобальной. Впрочем, может быть как раз в этом и состоит моя ошибка? - Тогда дело за малым - вопрос, как сделать по-другому?
|
|
« Последнее редактирование: 26-11-2009 14:12 от Kultura »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 26-11-2009 15:31 » |
|
Kultura, всегда можно сделать так, что в статическую функцию передастся указатель на объект, который внутри функции будет играть роль this. И, по моему, это единственный возможный вариант использования колбэков для работы с объектом
|
|
|
Записан
|
|
|
|
Kultura
Помогающий
Offline
|
|
« Ответ #4 : 26-11-2009 16:06 » |
|
Алексей1153++, отправка сообщения с указателем this в одном из параметров? А если нужно пользоваться переменными класса внутри стандартных сообщений; как быть с процедурой субклассинга? Или ты говоришь о чем-то другом, расскажи подробнее
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #5 : 26-11-2009 17:16 » |
|
я не про сообщения, а про callback. Тебя же это смутило - что callback статический. Но видишь же, в него передаётся хендл окна (аналог this). А для каждого типа окна - оконная процедура своя. Теоретически я понимаю, как это всё разгрести, и разгрёб бы, если столкнусь с задачей )
Приложи проект, может кто-нибудь найдёт время пример тебе сделать.
|
|
« Последнее редактирование: 26-11-2009 17:16 от Sel »
|
Записан
|
|
|
|
Kultura
Помогающий
Offline
|
|
« Ответ #6 : 26-11-2009 18:59 » |
|
Да, мне не понятно о чем идет речь. Как связать HWND и указатель на объект?
Прикладываю пример. Почистил класс туллтипа. Оставил конструктор - в нем создается некое окно, его процедура объявлена в классе туллтипа как статическая. Еще оставил вектор туллзов - вложеный статический объект, который используется в callback поцедурах. Кстати, он хранит описатель и указатель на процедуру для окошек, к которым прикрепляем подсказку. Так же оставил вторую static callback процедуру субклассинга, который производится для добавляемых окошек (эта процедура посылает окну подсказки сообщение WM_NOTIFY при движении мыши). Оставил субклассинг, т.к. не понятно, как получать доступ к указателю на объект еще и из этой процедуры.
Алексей1153++, хотя не знаю, стоит ли отнимать у кого-то время проектом, но по твоему совету выкладываю. Кстати, может быть, есть что-то почитать по данному вопросу?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #7 : 26-11-2009 19:21 » |
|
Как связать HWND и указатель на объект?
в общем случае - никак. Но напрямую связано с окном - ведь это же ХЕНДЛ окна! )) Есть хендл - можно слать сообщение окну. Ну тут с ходу я тоже не придумал, как полную свободу действий получить. Щас гляну проект хотя не знаю, стоит ли отнимать у кого-то время проектом
как раз время будет отниматься, когда проект не приложен - ведь помогающему нужно сообразить, о чём речь, написать код, всё проверить. А это лень, поэтому помогающий может тупо пройти мимо Всегда делай по максимуму работу за помогающего. Тогда и помогут быстрее, да и сам вдруг найдёшь ответ. Почитать ничего не посоветую - я ж не апишник, буду сейчас вникать в код, может и соображу что
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 26-11-2009 19:28 » |
|
кстати, по ходу дела, компилятор советует: 'wcscpy': This function or variable may be unsafe. Consider using wcscpy_s instead. 'swprintf': swprintf has been changed to conform with the ISO C standard, adding an extra character count parameter. прислушайся, дело говорит
|
|
|
Записан
|
|
|
|
Kultura
Помогающий
Offline
|
|
« Ответ #9 : 26-11-2009 19:44 » |
|
даа, на warning-ах попалился
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 26-11-2009 20:12 » |
|
сижу, разбираюсь, пока ещё не понял, что можно сделать )
|
|
« Последнее редактирование: 27-11-2009 05:47 от Sel »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #11 : 26-11-2009 20:56 » |
|
вопрос - а почему LRESULT CALLBACK EncToolTip::SubclassProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { ..... SendMessage (m_hWndToolTip, WM_NOTIFY, (WPARAM) & nmh, lParam); .....
а не SendMessage (hWnd, WM_NOTIFY, (WPARAM) & nmh, lParam);
? Ведь только это и тормозило. А в остальном всё решилось добавлением std::map<HWND,const EncToolTip*> m_handle_to_prt; см аттач. Визуально ничего не поменялось, но компилится )))
|
|
|
Записан
|
|
|
|
Kultura
Помогающий
Offline
|
|
« Ответ #12 : 27-11-2009 15:12 » |
|
вопрос - а почему
Ведь только это и тормозило.
Потому что процедура субклассинга получает в параметре HWND hWnd дескриптор окошка, которое "субклашено". Т.е. hWnd != m_hWndToolTip. Дальше процедура используется для оповещения окна подсказки. Например, сейчас, как у тебя, второе окно (m_hWndToolTip) не получает сообщения WM_NOTIFY, его получают окна кнопок при наведении мышки на них. Пример посмотрел, спасибо. Действительно увязываются HWND и указатель на объект, это уже отлично Но все еще остается проблема с процедурой субклассинга. Как я написал выше, в ней известен описатель "субклашеного" окошка; изнутри уже так просто не получится знать описатель окна, для которого существует объект. P.S. А указатели в map обязательно должны быть константными? Тогда нельзя менять ничего в объектах, хотя вроде бы без этого можно и обойтись.
|
|
« Последнее редактирование: 27-11-2009 17:17 от Sel »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #13 : 27-11-2009 15:54 » |
|
ну, мозг у меня на субклассинге, основанном на хендлах, не тренирован, поэтому туплю откровенно Но в любом случае, есть два инструмента: 1) map (или любой самописный аналог, но map ведь уже есть.) Только тут надо строго следить за тем, чтобы пара указатель-хендл была валидной, то есть чтобы и указатель и хендл существовали и принадлежали одному объекту. Если что то перестало существовать, то пару надо удалить 2) имеется хендл на окно - значит всегда можно послать окну сообщение. Бывают пользовательские сообщения - больше WM_USER /* * NOTE: All Message Numbers below 0x0400 are RESERVED. * * Private Window Messages Start Here: */ #define WM_USER 0x0400
определяй и властвуй Ничего не поделаешь тут - окна общаются в винде сообщениями. P.S. А указатели в map обязательно должны быть константными? Тогда нельзя менять ничего в объектах, хотя вроде бы без этого можно и обойтись. вместо std::map<HWND, const EncToolTip*>
определи как std::map<HWND, EncToolTip*>
|
|
« Последнее редактирование: 27-11-2009 17:16 от Sel »
|
Записан
|
|
|
|
|
Kultura
Помогающий
Offline
|
|
« Ответ #15 : 29-11-2009 12:23 » |
|
Впринципе, можно при субклассинге точно так же связывать хендлы окошек с объектом, ответственным за субклассинг. Спасибо за помощь
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #16 : 29-11-2009 13:03 » |
|
Я помнится в ATL, когда хитрый туллбар писал, то выкручивался следующим образом: 1. Создал класс, содержащий массив структур хендл+указатель на объект, с статическими методами добавления, получения объекта. 2. В конструкторе объекта в вышеуказанный класс-массив добавлялся вновь созданный объект, где увязывался хендл окна объекта и указатель на объект. 3. Перечисляя объекты из класса-массива в процедуре сабклассинга по хендлу окна находился указатель на соответствующий окну объект.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #17 : 29-11-2009 13:33 » |
|
можно ещё два параллельных мапа держать (ну и синхронизировать чётко их)
std::map<HWND, указатель> map1; std::map<указатель, HWND> map2;
тогда поиск в обе стороны будет быстрым и удобным
|
|
|
Записан
|
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #19 : 16-12-2009 18:26 » |
|
а если есть MFC, зачем это всё ? )
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #20 : 17-12-2009 07:40 » |
|
Лёш, это попытка заменить ATL и MFC. Смущает другое: So I looked at the source for MFC and ATL and some other window class library and stole the ideas and wrote my own. В чём фишка? Что же там тогда "своё"? Другое название классов? Ну-ну...
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "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."
|
|
|
Kultura
Помогающий
Offline
|
|
« Ответ #21 : 17-12-2009 15:26 » |
|
Алексей1153++, но не у всех есть коммерческая студия, и многие пользуются express, в которой отсутствуют MFC и ATL.
|
|
« Последнее редактирование: 17-12-2009 15:29 от Kultura »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #22 : 18-12-2009 03:50 » |
|
Kultura, японятия не имею, коммерческая она у меня или нет
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #23 : 18-12-2009 04:38 » |
|
Леш, короче пыратка
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #24 : 18-12-2009 04:42 » |
|
попалили ))
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #25 : 18-12-2009 07:35 » |
|
Алексей1153++, но не у всех есть коммерческая студия, и многие пользуются express, в которой отсутствуют MFC и ATL.
ATL, если мне не изменяет память, можно прикрутить - он свободный и у Microsoft в свободном доступе есть. Только не уверен за версию.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #26 : 18-12-2009 07:57 » |
|
Kultura, а почему бы не посмотреть в сторону WTL? Она тоже бесплатная. зы Алексей1153++, но не у всех есть коммерческая студия, и многие пользуются express, в которой отсутствуют MFC и ATL. А использование других библиотек, с украдеными у других идеями, не противоречит этическим принципам? Надо только помнить одно, когда на продуктах созданых с использованием этих библиотек начнутся зарабатываться денюшки, то могут за попу взять не хуже, чем за использование пиратских копий IDE. И тем вернее, чем больше денюшек на этом будет заработано.
|
|
« Последнее редактирование: 18-12-2009 08:02 от Джон »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "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."
|
|
|
lag
Участник
Offline
|
|
« Ответ #27 : 18-12-2009 08:11 » |
|
У меня в 2008 express MFC-проект компилится и отлаживается, только rc-файл вручную создавал.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #28 : 18-12-2009 08:15 » |
|
lag, имеется в виду, что в мастере проектов нет шаблонов для их создания. Конечно можно всё делать ручками. Можно даже свои шаблоны написать и не мучиться.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "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."
|
|
|
|
|