C++/MFC Detectarea unei ferestre noi

Intrebari legate de programarea cu biblioteci precum MFC, ATL, WTL si GDI+.
Post Reply
rilley
Junior
Junior
Posts: 22
Joined: 11 Feb 2010, 01:24
Judet: Harghita

C++/MFC Detectarea unei ferestre noi

Post by rilley » 19 Feb 2012, 14:31

Buna ziua,


Cum as putea in C++/MFC sa detectez cand a aparut o fereastra oarecare?

Stiu metoda prin FindWindow(...,...), dar problema este ca numai atunci functioneaza doar cand il pun intr-un WHILE, stiti voi alta metoda? ex mesaje din AFX/MFC cand se creaza un oarecare dialog?

PS: Sunt la inceput de drum, stiu programare C++/MFC Clase, Vreau sa dezvolt o aplicatie prin care imi afiseaza toate ferestrele deschise, si am nevoie si la crearea ferestrelor noi, sa apara in program...


Multumesc



User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: C++/MFC Detectarea unei ferestre noi

Post by Ovidiu Cucu » 19 Feb 2012, 14:49

Nu trebuie sa recurgi la while ci poti seta un timer in care sa-ti refresezi lista de ferestre cu EnumWindows si/sau EnumChildWindows.
Vezi CWnd::SetTimer.

Daca vrei sa prinzi momentul cand se creaza o fereastra, poti face un (CBT) hook.
Pentru mai multe detalii, vezi SetWindowsHookEx function.

rilley
Junior
Junior
Posts: 22
Joined: 11 Feb 2010, 01:24
Judet: Harghita

Re: C++/MFC Detectarea unei ferestre noi

Post by rilley » 19 Feb 2012, 15:02

Mersi de raspuns


Daca folosesc SetTimer, ar fi o solutie mai buna sa prind si ferestrele noi fara a se epuiza din resursele calculatorului (cum face while ridica CPU la 100%)?

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: C++/MFC Detectarea unei ferestre noi

Post by Ovidiu Cucu » 19 Feb 2012, 15:04

Pai, de aia s-au inventat timerele, thread-urile, functiile callback si alte chestii din astea. ;)

rilley
Junior
Junior
Posts: 22
Joined: 11 Feb 2010, 01:24
Judet: Harghita

Re: C++/MFC Detectarea unei ferestre noi

Post by rilley » 19 Feb 2012, 19:51

Re,

Cu CBT hook si SetWindowsHookEx, nu prea am inteles cum functioneaza,

Ideea sa refreshuesc EnumWindows si/sau EnumChildWindows, ar fi buna, am incercat cu crearea de Threaduri :
EX:
runner *rr = new runner();
rr->start();

void runner::run(){
while(isRunning()){
///////////////////////////////
}
}

Dar imi consuma 20% din procesor, o alta idee ar fi? Imi trebuie ceva dar sa nu imi consume din resursele procesorului!
Imi poti da un exemplu concret cu SetTimer?

Multumesc!




EDIT2:

Am gasit functionarea lui SetTimer:

#define STRICT 1
#include <windows.h>
#include <iostream.h>

VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime) {
cout << "Time: " << dwTime << '\n';
cout.flush();
}

int main(int argc, char *argv[], char *envp[]) {
int Counter=0;
MSG Msg;
UINT TimerId = SetTimer(NULL, 0, 500, &TimerProc);

cout << "TimerId: " << TimerId << '\n';
if (!TimerId)
return 16;
while (GetMessage(&Msg, NULL, 0, 0)) {
++Counter;
if (Msg.message == WM_TIMER)
cout << "Counter: " << Counter << "; timer message\n";
else
cout << "Counter: " << Counter << "; message: " << Msg.message << '\n';
DispatchMessage(&Msg);
}

KillTimer(NULL, TimerId);

return 0;
}


Multumesc!

User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: C++/MFC Detectarea unei ferestre noi

Post by bu7ch3r » 19 Feb 2012, 23:52

Tie numai asta iti trebuie. Poti adapta asta la clasa dialogului. Aaaa...si incurci varza cu barza, asta nu e MFC :)
Daca vrei ca un thread sa nu-ti consume din procesor, pune un sleep micut in el : sleep(20), sleep(500) si gata, e ca un timer ;)

Code: Select all

#define STRICT 1 
#include <windows.h>
#include <iostream.h>

VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime) {
//aici da refresh la ferestre
}

int main(int argc, char *argv[], char *envp[]) {

UINT TimerId = SetTimer(NULL, 0, 500, &TimerProc);

KillTimer(NULL, TimerId); //poti sa faci asta in destructorul clasei dialogului

return 0;
}
Poti sa nu-ti faci callback-ul ala pt ca ai un mesaj smecher tare : ON_WM_TIMER -----> CDlgDlg::OnTimer( UINT nIDEvent ) ;) Pt asta tre sa folosesti SetTimer cu un eventID in loc de NULL.

Bafta!
Cu stima,
Lupu Claudiu

rilley
Junior
Junior
Posts: 22
Joined: 11 Feb 2010, 01:24
Judet: Harghita

topmost, transparenta, hwnd findwindow process

Post by rilley » 20 Feb 2012, 16:06

Multumesc tuturor pentru suport,

Am zis sa nu mai fac un alt topic, as mai avea nevoie de inca ceva,


1. Sa trimit catre o fereastra oarecare, gasita prin FindWindow, de ex: transparenta 100%;

2. Sa setez catre o fereastra oarecare, gasita prin FindWindow, tot timpul sa nu isi piarda on top ( sa fie tot timpul focus pe ea, si daca dau click pe alceva );

3. Cum as putea verifica daca HWND gasit prin FindWindow, coincide unui process;


Multumesc!

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: C++/MFC Detectarea unei ferestre noi

Post by Ovidiu Cucu » 20 Feb 2012, 17:05

M-as fi bucurat sa deschizi nu unul ci trei topicuri noi.
E mai bine ca sa fie topicul si problema decat sa le amestecam pe toate intr-unul singur.

In fine, astea sunt raspunsurile:
  1. Adauga WS_EX_LAYERED la stilul extins apoi cheama CWnd::SetLayeredWindowAttributes.

    Code: Select all

       CWnd* pWnd = CWnd::FindWindow(_T("Notepad"), NULL);
       if(NULL != pWnd)
       {
          pWnd->ModifyStyleEx(0, WS_EX_LAYERED);
          BYTE bAlpha = 0; // 100% transparent (255 for 100% opaque)
          pWnd->SetLayeredWindowAttributes(0, bAlpha, LWA_ALPHA);
       }
  2. Chema CWnd::SetWindowPos cu CWnd::wndTopMost.

    Code: Select all

       CWnd* pWnd = CWnd::FindWindow(_T("Notepad"), NULL);
       if(NULL != pWnd)
       {
          UINT nFlags = SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE; 
          pWnd->SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, nFlags);
       }
  3. GetWindowThreadProcessId function does the trick:

    Code: Select all

       CWnd* pWnd = CWnd::FindWindow(_T("Notepad"), NULL);
       DWORD dwProcessID = 0;
       DWORD dwThreadID = ::GetWindowThreadProcessId(pWnd->GetSafeHwnd(), &dwProcessID);
       if(0 != dwThreadID)
       {
          // compare whith reference process ID.
       }

rilley
Junior
Junior
Posts: 22
Joined: 11 Feb 2010, 01:24
Judet: Harghita

Re: C++/MFC Detectarea unei ferestre noi

Post by rilley » 20 Feb 2012, 18:16

re:

Am o singura problema cu 2:

Eu folosesc un SetTimer pentru a pune tot timpul FOCUS pe acea fereastra, dar nu reusesc, ce trebuie sa pun in CALLBACK?

Am asa:
CALLBACK >>>
HWND windowHandle = FindWindowA(NULL, "Notepad");
if (windowHandle!=NULL){
//SetWindowPos(windowHandle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE);
//SetWindowPos(windowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOREDRAW | SWP_NOMOVE);
//ShowWindow(windowHandle, SW_RESTORE);
//SwitchToThisWindow(windowHandle, true);
//SetActiveWindow(windowHandle);
//BringWindowToTop(windowHandle);
//SetFocus(windowHandle);
}


Am incercat fiecare varianta, si nu reusesc sa am tot timpul FOCUS pe acea fereastra, desi e pe topmost, dupa ce dau click pe alta fereastra isi pierde focusul....

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: C++/MFC Detectarea unei ferestre noi

Post by Ovidiu Cucu » 20 Feb 2012, 19:15

Pai daca e topmost nu inseama ca are si tot timpul focusul.
N-o rezolvi nici cu timerul.
La ce-ti trebuie asa ceva? Daca as sti scopul practic/concret, poate as gasi o solutie alternativa.

rilley
Junior
Junior
Posts: 22
Joined: 11 Feb 2010, 01:24
Judet: Harghita

Re: C++/MFC Detectarea unei ferestre noi

Post by rilley » 20 Feb 2012, 19:49

Dupa cum spuneam vreau sa dezvolt o aplicatie prin care imi afiseaza toate ferestrele deschise, pe langa aceasta, vreau sa am mai multe atribuite fiecarei ferestre, cat timp aplicatia mea ruleaza ce atribuite ii dau unei ferestre oarecare din lista, sa functioneze corect.

-> Un exemplu mai concret ar fi, setez aplicatia sa functioneze pe o anumita fereastra, dupa ce apare fereastra pentru a introduce o parola (gen folder lock), dar in acelasi timp primesc un mesaj pe yahoo (isi pierde din focus, tipic), dupa ce am introdus parola, nu mai am nevoie de FULL FOCUS pe acea fereastra.

PS: Daca chiar nu merge atunci renunt la chestia cu full focus!


Mersi pentru suport!

User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: C++/MFC Detectarea unei ferestre noi

Post by bu7ch3r » 21 Feb 2012, 14:51

Incearca asa:

Code: Select all

HWND windowHandle = FindWindowA(NULL, "Notepad");
if (windowHandle!=NULL){
SetFocus(windowHandle);
BringWindowToTop(windowHandle);//cu asta sau fara asta
SetWindowPos(windowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOREDRAW | SWP_NOMOVE);
}
Este o problema pe os > XP, trebuie sa dai focus la fereastra inainte s-o faci topmost.BTW: poti sa scoti si SWP_NOREDRAW.

L.E. E de ajuns sa apelezi asta numai o data. Daca o faci cum trebuie fereastra ramane tot timpul topmost.
Last edited by bu7ch3r on 21 Feb 2012, 14:55, edited 1 time in total.
Cu stima,
Lupu Claudiu

User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: C++/MFC Detectarea unei ferestre noi

Post by bu7ch3r » 21 Feb 2012, 14:52

Code: Select all

  UINT nFlags = SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE; 
      pWnd->SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, nFlags);
Am impresia ca daca pui SWP_NOACTIVATE ca flag wndTopMost e ignorat...:-??
Cu stima,
Lupu Claudiu

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: C++/MFC Detectarea unei ferestre noi

Post by Ovidiu Cucu » 21 Feb 2012, 16:36

bu7ch3r wrote:

Code: Select all

  UINT nFlags = SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE; 
      pWnd->SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, nFlags);
Am impresia ca daca pui SWP_NOACTIVATE ca flag wndTopMost e ignorat...:-??
Nu, de ce sa fie ignorat?
Daca pun HWND_TOPMOST respectiv CWnd::wndTopMost, atunci fereastra devine topmost oricum, adica sta tot timpul in fata celorlalte fereste non-topmost (care n-au stilul WS_EX_TOPMOST).
Daca pun si flag-ul SWP_NOACTIVATE atunci nu este activata, adica daca initial era inactiva, ramane tot asa.

User avatar
cristianamarie
Membru++
Membru++
Posts: 480
Joined: 12 Mar 2009, 18:47
Judet: Iaşi
Location: Iasi

Re: C++/MFC Detectarea unei ferestre noi

Post by cristianamarie » 21 Feb 2012, 22:25

Topmost nu are neaparat focus. Un dialog de Find poate fi topmost in timp ce focusul e in document.
Nuclear launch detected

Post Reply