Page 1 of 1

EnumWindows

Posted: 27 May 2008, 06:36
by viorel2005
Salut

Cum folosesc o functie de tip callback(din Win32) intr-un proiect Visual C++ cu MFC?Ma intereseaza sablonul de scriere al codului.Exemplu:EnumWindows intr-o aplicatie de tip Dialog.Am incercat ce este la adresa:
http://www.flounder.com/callbacks.htm in VC++ si obtin o eroare la run-time.

Re: EnumWindows

Posted: 27 May 2008, 07:32
by neagu_laurentiu
Cum folosesc o functie de tip callback(din Win32) intr-un proiect Visual C++ cu MFC? Exemplu:EnumWindows
Callback e un stil/concept/abordare/tehnica iar in link-ul tau iti spune clar:

Code: Select all

::EnumWindows(...)
Si studiaza operatorul "::" ca e nevoie !

Re: EnumWindows

Posted: 27 May 2008, 07:45
by Ovidiu Cucu
Sau ai uitat CALLBACK (__stdcall) din declaratia functiei, sau nu ai facut-o static (in caz ca ai pus-o membru intr-o clasa), sau... Nu putem sti daca nu ne arati codul exact.

Re: EnumWindows

Posted: 27 May 2008, 08:44
by Marius Bancila
Am scris mai demult un articol despre functiile de callback: http://www.codeguru.com/cpp/cpp/cpp_mfc ... hp/c10557/.

Re: EnumWindows

Posted: 27 May 2008, 10:22
by Ovidiu Cucu
"Sablonul" ar fi cam urmatorul:
  1. Functia callback pe care o dai ca parametru la EnumWindows trebuie sa aiba calling convention __stdcall. CALLBACK este doar un alias "programmer's friendly" pentru __stdcall, mai binezis un macro definit undeva prin headere din windows SDK.
  2. Poti sa folosesti o functie globala, dar de dragul principiilor OOP, mai bine o pui membru static. Daca nu o pui static, atunci se schimba semnatura din cauza acelui "this" si ar trebui sa dea eroare la compilare.
  3. Poti folosi cel de-al doilea parametru (tip LPARAM) pentru a transmite informatii pe care sa le folosesti in functia callback. De obicei trimiti un handle de fereastra (HWND) sau un pointer la un obiect.
Un "sablon" de cod pentru o aplicatie MFC dialog-based ar arata cam asa:

Code: Select all

class CMyDialog : public CDialog
{
protected:
    static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam);
// ...
};

Code: Select all

BOOL CALLBACK CMyDialog::EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
    BOOL bRet = TRUE;
    CWnd* pWnd = CWnd::FromHandle(hWnd);
    CMyDialog* pDlg = (CMyDialog*)lParam;
    // ... ENJOY!
    // ...
	
    return bRet ; // TRUE to continue; FALSE to stop enumeration. 
}

Code: Select all

void CMyDialog::OnButtonEnum()
{
    BOOL bRet = ::EnumWindows(EnumWindowsProc, (LPARAM)this);
    if(! bRet)
    {
        DWORD dwError = ::GetLastError();
        // ...display error if any...
    }
}
Bineiteles, pentru mai multe informatii, iti recomand sa citesti si articolul lui Marius.
Si... last but not the least, te rog, atunci cand obtii o eroare la run-time sau la compile-time sa ne spui si noua ce zice. De asemenea o mica bucatica de cod in care sa ne arati ce ai facut si cam pe unde a aparut eroarea, nu strica deloc.