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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как получить список элементов диалогового окна  (Прочитано 33006 раз)
0 Пользователей и 1 Гость смотрят эту тему.
AndrewF
Гость
« : 07-11-2005 13:15 » 

Есть диалоговое(HANDLE на него ) окно с несколькими элементами среди которых есть ComboBox как получить ID либо HANDLE этого элемента? Может быть можно получить список HANDL ов всех элементов окна? 
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 07-11-2005 13:52 » 

если установить фокус на контрол, а затем щёлкнуть мышью по определённому окну СВОЕЙ проги, то в обработчике
CWnd::OnSetFocus
можно поиметь хендл.

если просто список надо - фиг его знает Улыбаюсь мож просканировать GetDlgItem? Но это долго...
Записан

Джон
просто
Администратор

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

« Ответ #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? Но это долго...
Если можно поясните подробнее...
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline 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);
}

тут просто устанавливается текст, но так - только для того что может получить фокус...

Как -то надо из позиции мыши...
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline 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);
}
Записан
Джон
просто
Администратор

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

« Ответ #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
Спасибо всем кто принял участие в обсуждении))))
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline 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
Команда клуба

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

« Ответ #11 : 15-11-2005 13:02 » 

А если сделать так.
Повесить глобальный хук. Допустим обрабатывать будем нажатие средней клавиши мыши. Средней клавишей мыше щелкаем на нужном нам элементе окна или окне и получаем его хендл из структуры tafMSG.
ИМХО так проще и поток не нужен. Или я не прав?
Записан

ещё один вопрос ...
Джон
просто
Администратор

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

« Ответ #12 : 15-11-2005 13:34 » 

nikedeforest, можно в этом случае ещё проще, если у тебя есть координаты мыши. Ты всегда можешь получить окно под курсором и хук не нужен:
Цитата: MSDN
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
Команда клуба

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

« Ответ #13 : 15-11-2005 13:49 » 

точно, а я и  забыл про эту функцию. Помнил что-то есть, а что именно забыл Улыбаюсь.
Цитата
Меня интересует другое - как определить "нужный" комбобокс? Например у меня их 10 штук на форме. Ни хэндлы, ни ID их не известны.
Ты имеешь ввиду, что при этом нельзя "помогать" программе. Т.е. пользователь не щелкает мышкой и т.п.?
Записан

ещё один вопрос ...
rpt
Гость
« Ответ #14 : 15-11-2005 13:56 » 

получил хэндл окна, получи всех детей этого окна , проерь IsKindOf комбобокс? если да - вызови у него первый элемент списка (текст) и проверь нужнен он тебе или нужен другой комбобокс.
Записан
Джон
просто
Администратор

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

« Ответ #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
Команда клуба

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

« Ответ #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++ » Записан

ещё один вопрос ...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline 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
Команда клуба

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

« Ответ #18 : 16-11-2005 12:31 » 

Ну с текстом да.
А как насчет клика?
Записан

ещё один вопрос ...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline 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
Команда клуба

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

« Ответ #20 : 16-11-2005 14:06 » 

Вот как пробовал
Код:
SendMessage(hw_client,WM_CLOSE,MK_LBUTTON,MAKELONG(1,1));
Эффект следующий.
Если это сообщение посылаются окну (элементу) своего приложения, то окно закрывается (кнопка пропадала, было забавно Улыбаюсь). Если же это посылаются чужому окну и его эл-ту, то ничего не происходит.
Короче, пока единственное чего я достиг, исдеваясь над чужими окнами,- это изменять их текст. Щелкнуть и закрыть их не получается.
А очень охото Улыбаюсь. Давайте думать вместе Ага.
Записан

ещё один вопрос ...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 16-11-2005 14:21 » 

nikedeforest , а с WM_COMMAND  не получается?
Записан

nikedeforest
Команда клуба

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

« Ответ #22 : 16-11-2005 14:38 » 

Пока не попробовал.
Я пробовал так
Код:
SendMessage(hw_client,WM_COMMAND,0,0);
Так не работало.
Сейчас попробую как ты сказал.
Записан

ещё один вопрос ...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #23 : 16-11-2005 14:40 » 

Код:
SendMessage(hw_client,WM_COMMAND,0,0);

- а так и не получится, ни ИД , ни хендла ...
Записан

nikedeforest
Команда клуба

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

« Ответ #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
Команда клуба

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

« Ответ #25 : 18-11-2005 12:18 » 

Алексей, у нас с тобой похоже идеи кончились, а другим наверное не интересно, а жаль Жаль.
Записан

ещё один вопрос ...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #26 : 18-11-2005 12:19 » 

nikedeforest , а Spy++ не смотрел, прилетают сообщения или нет?
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines