Enumwindows

  • Автор темы solova
  • Дата начала
S

solova

Гость
#1
Нужно найти хэндл окна по части его заголовка.
И в случае успеха\провала вывести Мессаджбокс с уведомлением успех\провал
Есть функция EnumWindows()
для неё CALLBACK вроде написал
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">CALLBACK</div></div><div class="sp-body"><div class="sp-content">
C++:
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
HWND HendlOkna;
char  buf[11]=" - Блокнот";
char  buf2[256];
if(::GetWindowText(hwnd,(LPWSTR)buf2, sizeof(buf2)))//(LPWSTR)
{
if(strstr(buf2,buf)!=NULL)
{
HendlOkna=hwnd;
return FALSE;
}
}
return TRUE;//---------------------------продолжить перебор
}
но что надо тут писать ? (чтоб выводило мессаги успех\провал)
if(EnumWindows((WNDENUMPROC)EnumWindowsProc, NULL))
{
////
}
Всё никак не могу понять кто кому и когда передаёт тру-фолсы
Можете объяснить или ссыланьку с подробным описанием про тру-фолсы(естественно для EnumWindows)
хотя если с мессагами (успех\провал) будет кодик то я сам разберусь.

А как вытянуть значение "HendlOkna" из COLLBACK-a???
 

lazybiz

Well-Known Member
03.11.2010
1 339
0
#2
C++:
HWND HendlOkna;

BOOL CALLBACK enum_proc( HWND hwnd, LPARAM lParam )
{
char * buf = "Блокнот";
char  buf2[256];
if ( GetWindowText( hwnd, buf2, 256 ) ) {
if ( strstr( buf2, buf ) != NULL ) {
HendlOkna = hwnd;
return FALSE;
}
}
return TRUE;
}

main()
{
...
HendlOkna = NULL;
if ( EnumWindows( enum_proc, NULL ) ) {
if ( HendlOkna ) {
MessageBox( NULL, "ok", "ok", MB_OK );
} else {
MessageBox( NULL, "xep", "xep", MB_OK );
}
}
...
}
 
S

solova

Гость
#3
так уже пробовал ,
постоянно "хер" пишет хотя окно открыто
и даже если написать в COLLBACK-e
C++:
if(strstr(buf2,buf)!=NULL)
{
HendlOkna = hwnd;
if ( HendlOkna )
MessageBox(NULL,L"ok2", L"ok2", MB_OK );
//MessageBox(NULL,(LPCWSTR)buf2,L"calback",2);
//*(HWND*)lParam = hwnd;
return FALSE;
}
сообщение не выводится
но если перед strstr() написать MessageBox(NULL,(LPCWSTR)buf2,L"calback",2); он выводит по очереди названия всех окон в том числе и Блокнота.
получается что через strstr() не проходит.
 

lazybiz

Well-Known Member
03.11.2010
1 339
0
#4
Рабочий вариант.
C++:
#include <windows.h>
#include <iostream.h>

HWND	g_hWnd;

BOOL CALLBACK enum_proc( HWND hWnd, LPARAM lParam )
{
char	buffer[1024];
if ( GetWindowText( hWnd, buffer, 1024 ) ) {
if ( strstr( buffer, (char *)lParam ) ) {
g_hWnd = hWnd;
return FALSE;
}
}
g_hWnd = NULL;
return TRUE;
}

int main()
{
EnumWindows( enum_proc, (LPARAM)"Блокнот" );
if ( g_hWnd ) {
MessageBox( NULL, "ok", "ok", MB_OK );
} else {
MessageBox( NULL, "xep", "xep", MB_OK );
}
return 0;
}
 
S

solova

Гость
#6
ХАА почему то в буффер(не важно почему) запись идёт такая (Б0л0о0к0н0о0т...) через нули
ща попробую переделать кодик
таак ,это не нули это NULL.

В "Б0л0о0к0н0о0т" я все нули заменил NULL теперь strstr() работает ну и вообще программка работает.
только надо писать EnumWindows((WNDENUMPROC)&EnumWindowsProc,NULL)
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">CALLBACK</div></div><div class="sp-body"><div class="sp-content">
C++:
HWND g_hWnd;
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
char	buffer[1024];
char	test[14]="Б*л*о*к*н*о*т";
for(int p=1;p<14;p=p+2)
test[p]=NULL;
if(::GetWindowText(hwnd,(LPWSTR)buffer, 1024))
{
if (strstr(buffer,test)
{
g_hWnd = hwnd;
//return FALSE;
}
}
//g_hWnd = NULL;
return TRUE;
}
если оставить "g_hWnd = NULL;" то не зависимо есть окно или нету мне пишет "хер"
если оставить "return FALSE;" то ни какой мессаги не будет,ну а если убрать как я понял окна будут перечисляться бесконечно или как?

<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">ButtonENUM</div></div><div class="sp-body"><div class="sp-content">
C++:
if (EnumWindows((WNDENUMPROC)&EnumWindowsProc,NULL))
{
if (g_hWnd!=NULL)
MessageBox(L"Ok", L"Хэндл", 0);
else
MessageBox(L"xep", 0, 0);
}
 

lazybiz

Well-Known Member
03.11.2010
1 339
0
#7
почему то в буффер(не важно почему) запись идёт такая (Б0л0о0к0н0о0т...) через нули
Потому что ты компилируешь в Юникоде. Функция GetWindowText определена как GetWindowTextW.

только надо писать EnumWindows((WNDENUMPROC)&EnumWindowsProc,NULL)
Так не надо писать. Процедура энумерации определена как typedef BOOL (CALLBACK* WNDENUMPROC)(HWND, LPARAM);
Два двоеточия перед GetWindowText() так же ставить не надо.

И вообще я не пойму... Кто в этой теме помощи просит ты или я? Если ты все знаешь лучше меня, тогда почему у тебя ничего не получается а у меня прекрасно работает?
 
S

solova

Гость
#8
вчера так запарился что программу тестил при выключенном блокноте и мне писалось "ОК"
сегодня начну всё заново может ещё что пропустил.

спасибо, работает
только вот ошибочка у вас была , если в Каллбаке оставить так
C++:
if (strstr(buffer,test)
{
g_hWnd = hwnd;
return FALSE;
}
то в случае когда мы добрались до нужного окна
C++:
if (EnumWindows(EnumWindowsProc,NULL))
уже не пройдёт поэтому правильнее будет
C++:
if (EnumWindows(EnumWindowsProc,NULL)==FALSE)
или
C++:
if (!EnumWindows(EnumWindowsProc,NULL))
но вот ещё проблема,Каллбак возвращает FALSE только когда нашёл нужное окно, а что он возвращает когда ничего не нашёл
я это к тому что у меня блокноты закрыты и сообщения "хер"(при g_hWnd=NULL) не пишутся ,точнее if (!EnumWindows... не проходит но при этом перечисления окон как то останавливаются
не могу понять как в калбаке определить что весь список уже проверен ,может какой нибудь Geterror нужно?
 

lazybiz

Well-Known Member
03.11.2010
1 339
0
#9
Ты вообще читаешь что я пишу? В моем последнем примере функция EnumWindows не взята в условие. Откуда ты взял это:
то в случае когда мы добрались до нужного окна
C++:
if (EnumWindows(EnumWindowsProc,NULL))
а что он возвращает когда ничего не нашёл
Он возвращает TRUE.
BOOL CALLBACK enum_proc( HWND hWnd, LPARAM lParam ) {
char buffer[1024];
if ( GetWindowText( hWnd, buffer, 1024 ) ) {
if ( strstr( buffer, (char *)lParam ) ) {
g_hWnd = hWnd;
return FALSE;
}
}
g_hWnd = NULL;
return TRUE;

}
Это был мой последний тебе ответ, т.к. ты уже з@#$%л.
 
S

solova

Гость
#10
а я думал он возвращает TRUE после каждого нахождения окна
(solova @ 7:03:2011 - 14:37) *
а что он возвращает когда ничего не нашёл
Он возвращает TRUE.
EnumWindowsProc
Возвращаемые значения
Чтобы продолжить перечисление, функция повторного вызова должна возвратить значение ИСТИНА (TRUE); чтобы остановить перечисление, она должна возвратить - ЛОЖЬ (FALSE).
EnumWindows
Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение - ноль.
ну вот собственно всё что я хотел узнать

Ещё раз спасибо.
 

lazybiz

Well-Known Member
03.11.2010
1 339
0
#11
Самый достоверный источник API - это MSDN.
То что я цитировал, но теперь уже с переводом на русский:
Из описания функции EnumWindows:
... If EnumWindowsProc returns zero, the return value is also zero. ...
Если EnumWindowsProc возвращает 0, то EnumWindows так же возвратит 0.
Именно поэтому нет смысла брать EnumWindows в условие.
 
S

solova

Гость
#12
я всё понял и переделал
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">код</div></div><div class="sp-body"><div class="sp-content">
C++:
int zf=EnumWindows(EnumWindowsProc,NULL);
if(zf==0)
if (g_hWnd != NULL)
MessageBox(L"Окно есть");
else
MessageBox(L"Окна нету");
но при закрытых блокнотах получаю g_hWnd!=NULL
hwnd 0x0001014c {unused=6488169 } HWND__ *
которое в последствие передаётся в g_hWnd
через Spy++ это что-то с FirstChildWindow:"Индикатор батарей"(хотя у меня стационар а не нубук)
и именно в этом окне текст
buffer 0x0012f028 "=48:0B>@ ......"
и strstr там что то находит

сделал проверку на первый символ(мне он известен) перед strstr()теперь нормально
 

lazybiz

Well-Known Member
03.11.2010
1 339
0
#13
S

solova

Гость
#14
блин не то скопировал , там я экспериментировал с ретурнами
вот как я переделал
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">код</div></div><div class="sp-body"><div class="sp-content">
C++:
EnumWindows(EnumWindowsProc,NULL);
if (g_hWnd != NULL)
MessageBox(L"Окно есть");
else
MessageBox(L"Окна нету");
И ещё раз спасибо.
 

lazybiz

Well-Known Member
03.11.2010
1 339
0
#15
А смысл дописывать "!= NULL" ?? Результат выполнения программы не изменится никак.

Поясняю:
NULL, он же 0, он же (void *)0
-1 ? "TRUE" : "FALSE"
0 ? "FALSE" : "TRUE"
1 ? "TRUE" : "FALSE"
Запомни, только (только!!!) 0 (NULL) является ложью!

Даже когда функция возвращает код ошибки (отличный от нуля), она возвращает TRUE !