AndrewF
Гость
|
|
« : 07-11-2005 13:15 » |
|
Есть диалоговое(HANDLE на него ) окно с несколькими элементами среди которых есть ComboBox как получить ID либо HANDLE этого элемента? Может быть можно получить список HANDL ов всех элементов окна?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #1 : 07-11-2005 13:52 » |
|
если установить фокус на контрол, а затем щёлкнуть мышью по определённому окну СВОЕЙ проги, то в обработчике CWnd::OnSetFocus можно поиметь хендл. если просто список надо - фиг его знает мож просканировать GetDlgItem? Но это долго...
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Online
Пол:
|
|
« Ответ #2 : 07-11-2005 14:46 » |
|
AndrewF, неувязочка - хэндлы генерятся системой, ID раздаёшь ты в ресурсах. Те тебе что-то одно должно быть известно.
если извесно ID, то хэндл можно получить: HWND ::GetDlgItem(HWND hDlg, int nIDDlgItem);
если известен хэндл, то ID можно получить: int ::GetDlgCtrlID(HWND hDlg);
есть так-же функции которые возвращают хэндл окна из позиции мыши. Но лучше сформулируй задачу поподробнее.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "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."
|
|
|
AndrewF
Гость
|
|
« Ответ #3 : 08-11-2005 05:39 » |
|
Но лучше сформулируй задачу поподробнее.
Попробую: нужно получить доступ к ComboBox диалогового окна другого приложения, есть хэндл этого окна но о его элементах ничего не известно, как это можно сделать(если можно конечно)? мож просканировать GetDlgItem? Но это долго...
Если можно поясните подробнее...
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #4 : 08-11-2005 06:09 » |
|
AndrewF , > Если можно поясните подробнее... Не, сканировать - это ОООООчень долго и ... бесполезно Забудь, глупость я сморозил. а вот >Попробую: нужно получить доступ к ComboBox диалогового окна другого >приложения, есть хэндл этого окна но о его элементах ничего не известно, > как это можно сделать(если можно конечно)? это сделай так - запускаешь инородное приложение. Запускаешь свою прогу. Нажимаешь определённую кнопку на своей проге , затем нажимаешь на комбобокс в инородной. Далее путей несколько. например - обработать OnKillFocus. у меня получилось так: void CmyDialog::OnKillFocus(CWnd* pNewWnd) { CDialog::OnKillFocus(pNewWnd);
HWND h; char txt[]="new text"; h=pNewWnd->GetSafeHwnd(); ::SendMessageA(h,WM_SETTEXT,0,(LPARAM)txt); }
тут просто устанавливается текст, но так - только для того что может получить фокус... Как -то надо из позиции мыши...
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #5 : 08-11-2005 06:15 » |
|
вот так получилось: POINT p; GetCursorPos(&p); CWnd *pw=WindowFromPoint(p); char txt[]="new text"; pw->SendMessage(WM_SETTEXT,0,(LPARAM)txt);
|
|
|
Записан
|
|
|
|
AndrewF
Гость
|
|
« Ответ #6 : 08-11-2005 08:38 » |
|
хм сообщение WM_KILLFOCUS возникает у меня лишь при закрытии диалогового окна,хотя казалось бы оно должно возникать каждый раз при смене фокуса, но этого не происходит? обрабатываю сообщение в переопределенной оконной процедуре, вот код: СLRESULT APIENTRY NewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_KILLFOCUS: MessageBox(NULL,"killfocus","",MB_OK); } return CallWindowProc(oldProcHandle,hWnd,message,wParam,lParam); }
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Online
Пол:
|
|
« Ответ #7 : 08-11-2005 09:32 » |
|
Попробую: нужно получить доступ к ComboBox диалогового окна другого приложения, есть хэндл этого окна но о его элементах ничего не известно, как это можно сделать(если можно конечно)?
В такой формулировке - никак. Даже если ты их всех "пробежишь" (в принципе это возможно - получить хэндлы детей), как ты узнаешь, что это ИМЕННО ТОТ ComboBox, который тебе нужен?
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "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."
|
|
|
AndrewF
Гость
|
|
« Ответ #8 : 09-11-2005 12:45 » |
|
ух.... список элементов получил с помощью функций GetWindow, GetNextWindow, дальше все свелось к субклассингу и обработке сообщения WM_COMMAND Спасибо всем кто принял участие в обсуждении))))
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #9 : 09-11-2005 13:09 » |
|
AndrewF, расскажи , интересно
|
|
|
Записан
|
|
|
|
AndrewF
Гость
|
|
« Ответ #10 : 10-11-2005 08:53 » |
|
ладно рассказываю: нужно было читать данные из диалогового окна Автокада, для нахождения окна создавал поток _beginthread(findPlotDialog,0,NULL); этот поток искал нужное окно, используя функцию FindWindow и переопределял оконную процедуру диалогового окна,сохраняя адрес старой процедуры(субклассинг): while (true) { handle=FindWindow(NULL,"Plot - Model"); if(handle!=NULL) { oldProcHandle=(WNDPROC)SetWindowLong(handle,GWL_WNDPROC,(LONG)NewWndProc); _endthread(); } }
дальше я обрабатывал сообщение WM_Command LRESULT APIENTRY NewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_COMMAND: //анализ от какого из элементов окна поступило сообщение //исп функции GetDlgItem и GetWindowText break; } return CallWindowProc(oldProcHandle,hWnd,message,wParam,lParam); }
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #11 : 15-11-2005 13:02 » |
|
А если сделать так. Повесить глобальный хук. Допустим обрабатывать будем нажатие средней клавиши мыши. Средней клавишей мыше щелкаем на нужном нам элементе окна или окне и получаем его хендл из структуры tafMSG. ИМХО так проще и поток не нужен. Или я не прав?
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Джон
просто
Администратор
Online
Пол:
|
|
« Ответ #12 : 15-11-2005 13:34 » |
|
nikedeforest, можно в этом случае ещё проще, если у тебя есть координаты мыши. Ты всегда можешь получить окно под курсором и хук не нужен: The WindowFromPoint function retrieves a handle to the window that contains the specified point. Меня интересует другое - как определить "нужный" комбобокс? Например у меня их 10 штук на форме. Ни хэндлы, ни ID их не известны.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "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."
|
|
|
nikedeforest
|
|
« Ответ #13 : 15-11-2005 13:49 » |
|
точно, а я и забыл про эту функцию. Помнил что-то есть, а что именно забыл . Меня интересует другое - как определить "нужный" комбобокс? Например у меня их 10 штук на форме. Ни хэндлы, ни ID их не известны.
Ты имеешь ввиду, что при этом нельзя "помогать" программе. Т.е. пользователь не щелкает мышкой и т.п.?
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
rpt
Гость
|
|
« Ответ #14 : 15-11-2005 13:56 » |
|
получил хэндл окна, получи всех детей этого окна , проерь IsKindOf комбобокс? если да - вызови у него первый элемент списка (текст) и проверь нужнен он тебе или нужен другой комбобокс.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Online
Пол:
|
|
« Ответ #15 : 16-11-2005 10:33 » |
|
nikedeforest, да я именно это и имел ввиду - конечно же пользователь должен определить какой именно элемент ему нужен - одних списков хэндлов и ID недостаточно. Те должны быть дополнительные условия, например я показал на него мышкой (самое простое и эффективное). Или это ЕДИНСТВЕННЫЙ или УНИКАЛЬНЫЙ контролл. rpt, в своём примере ввёл доп. условие - определение по заранее известному тексту. rpt, если ты собираешься использовать этот способ - учти два момента: 1. Нужный тебе текст не всегда будет стоять первым - например если это "нстоящий" комбобокс те едит с возможностью редактировать и вставлять новые айтемы. Лучше пробежаться по всем строчкам списка. 2. IsKindOf - функция исключительно MFC-шная, те чтобы она сработала класс контролла должен быть унаследован от CObject с объявленными макрсами DECLARE_DYNAMIC, DECLARE_DYNCREATE, или DECLARE_SERIAL + соответствущая имплементация IMPLEMENT_DYNAMIC, IMPLEMENT _DYNCREATE, или IMPLEMENT_SERIAL
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "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."
|
|
|
nikedeforest
|
|
« Ответ #16 : 16-11-2005 11:46 » |
|
По поводу взятьтекст у чужого окна. Как это правильно сделать, а то вот так HWND hw_client; CHAR capt_client[100];
GetWindowText(hw_client,capt_client,GetWindowTextLength(hw_client));
не работает. И еще, не подскажите как создать щелчок по кнопке чцжого окна. Вот этот код срабатывает, только на окнах (элементах) своего приложения, а на чужих не может. SendMessage(hw_client,WM_LBUTTONDOWN,MK_LBUTTON,MAKELONG(1,1)); SendMessage(hw_client,WM_LBUTTONUP,0,MAKELONG(1,1));
hw_client получаю с помощью глобального хука. Он 100% процентов работает, т.к. делаю так SendMessage(hw_client,WM_SETTEXT,0,LPARAM("It's my window"));
И менялся текст на чужой кнопке и едите и прочее. Все выше перечисленные действия я провожу не в ДЛЛ, а в основном приложении.
|
|
« Последнее редактирование: 04-12-2007 19:50 от Алексей1153++ »
|
Записан
|
ещё один вопрос ...
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #17 : 16-11-2005 12:12 » |
|
>>По поводу взятьтекст у чужого окна.
послать сообщение WM_GETTEXT
To send this message, call the SendMessage function as follows.
lResult = SendMessage( // returns LRESULT in lResult (HWND) hWndControl, // handle to destination control (UINT) WM_GETTEXT, // message ID (WPARAM) wParam, // = (WPARAM) () wParam; (LPARAM) lParam // = (LPARAM) () lParam; );
Parameters
wParam Specifies the maximum number of TCHARs to be copied, including the terminating null character. Windows NT/2000/XP:ANSI applications may have the string in the buffer reduced in size (to a minimum of half that of the wParam value) due to conversion from ANSI to Unicode.
lParam Pointer to the buffer that is to receive the text.
|
|
« Последнее редактирование: 16-11-2005 12:14 от Алексей1153 »
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #18 : 16-11-2005 12:31 » |
|
Ну с текстом да. А как насчет клика?
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #19 : 16-11-2005 13:46 » |
|
nikedeforest , с кнопкой не знаю . Возможно надо посылать WM_COMMAND родителю кнопки
достать родителя так: CWnd::GetParent() достать ID кнопки GetDlgCtrlID()
затем послать родителю
SendMessage( WM_COMMAND, (WPARAM)( ((ID кнопки &0x0000ffff)<<16) | (ID кнопки&0x0000ffff) ), (LPARAM)хендл кнопки);
хотя содержание WPARAM параметра точно не скажу - чёт не соображу, пробовать щас не буду...
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #20 : 16-11-2005 14:06 » |
|
Вот как пробовал SendMessage(hw_client,WM_CLOSE,MK_LBUTTON,MAKELONG(1,1));
Эффект следующий. Если это сообщение посылаются окну (элементу) своего приложения, то окно закрывается (кнопка пропадала, было забавно ). Если же это посылаются чужому окну и его эл-ту, то ничего не происходит. Короче, пока единственное чего я достиг, исдеваясь над чужими окнами,- это изменять их текст. Щелкнуть и закрыть их не получается. А очень охото . Давайте думать вместе .
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #21 : 16-11-2005 14:21 » |
|
nikedeforest , а с WM_COMMAND не получается?
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #22 : 16-11-2005 14:38 » |
|
Пока не попробовал. Я пробовал так SendMessage(hw_client,WM_COMMAND,0,0);
Так не работало. Сейчас попробую как ты сказал.
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #23 : 16-11-2005 14:40 » |
|
SendMessage(hw_client,WM_COMMAND,0,0);
- а так и не получится, ни ИД , ни хендла ...
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #24 : 16-11-2005 15:07 » |
|
HWND hw_cl_par= GetParent(hw_client); int ID=GetDlgCtrlID(hw_client); SendMessage(hw_cl_par,WM_COMMAND, (WPARAM)( ((ID&0x0000ffff)<<16) | (ID&0x0000ffff) ), (LPARAM)hw_client);
Эффект тот же, у своего приложения все закрывает, а у чужих не хочет, хотя текст меняет. Странно все это.
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
nikedeforest
|
|
« Ответ #25 : 18-11-2005 12:18 » |
|
Алексей, у нас с тобой похоже идеи кончились, а другим наверное не интересно, а жаль .
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #26 : 18-11-2005 12:19 » |
|
nikedeforest , а Spy++ не смотрел, прилетают сообщения или нет?
|
|
|
Записан
|
|
|
|
|