Thread: EnumWindowsProc

  1. #1
    Registered User
    Join Date
    Feb 2005
    Posts
    15

    EnumWindowsProc

    I am attempting to find all open windows (using a console project) and output their hWnd, class, and captions in the console. However I attempted this and for some reason it gives me a compiler error on the callback and says "cannot change from BOOL to WNDENUMPROC. Every other example I find compiles perfectly and uses the exact same statement. I don't know what I'm doing wrong. I attempted to cast it explicitly and still nothing.

    any ideas?

  2. #2
    VA National Guard The Brain's Avatar
    Join Date
    May 2004
    Location
    Manassas, VA USA
    Posts
    903
    Here is your function:
    Code:
    /*BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
    {
    	return false;
    }*/

    to me it doesn't make sense.. why pass in stuff when you are just returning false?

    Instead of making a function call.. you could just use FALSE
    • "Problem Solving C++, The Object of Programming" -Walter Savitch
    • "Data Structures and Other Objects using C++" -Walter Savitch
    • "Assembly Language for Intel-Based Computers" -Kip Irvine
    • "Programming Windows, 5th edition" -Charles Petzold
    • "Visual C++ MFC Programming by Example" -John E. Swanke
    • "Network Programming Windows" -Jones/Ohlund
    • "Sams Teach Yourself Game Programming in 24 Hours" -Michael Morrison
    • "Mathmatics for 3D Game Programming & Computer Graphics" -Eric Lengyel

  3. #3
    Registered User
    Join Date
    Feb 2005
    Posts
    15
    I had commented it out because I wanted to make sure that's where the error was coming from. As for returning false, I am not sure what I have to do, but it doesn't compile yet, so i'm taking it one obstacle at a time. Once it compiles then i'm going to somehow figure out the code inside of there (i just put return false so i wouldn't get a 'this function doens't return a vlue' compile error).

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    It can be helpful to include the exact error text and include the code inline instead of as an attachment if it is not very long. You can not use a normal member function as a Win32 callback. You can use a static member function or a normal non-member function. If needed this function can call the class member function.
    Code:
    BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
    {
        /* Normal non-member function. In turn we call the member function. */
        return ((Engine*) lParam)->EWP(hwnd, lParam);
    }
    
    
    Engine::Engine(string strClassName)
    {
    	ClassName = strClassName;
    	cout<<"Engine Constructor "<<strClassName<<endl;
    	EnumWindows(EnumWindowsProc, (LPARAM) this);
    }

  5. #5
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Thread moved to the Window's forum.

  6. #6
    Registered User
    Join Date
    Feb 2005
    Posts
    15
    anony, wow, that was a great explaination, i'm still figuring it out Maybe this isn't a good project to start out to do for someone whom just has the basics down.. Since I don't know what a non-normal function and such is.. Any chance of a slightly 'dumber' explaination...?

    Thank you for all the help so far guys. I will include in this the header and cpp files.

    Still won't compile, now it complains about redifinition... and can't convert hwnd to bool. I must not be following this correctly at all...
    Last edited by coldfusion244; 02-21-2005 at 11:58 AM.

  7. #7
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    A member function is a function that belongs to a class or structure. For example, all your Engine functions are member functions of the Engine class. A non-member function is a function that does not belong to a class or structure. A static member function is a function that belongs to a class but is declared with the static keyword.
    Code:
    /* This is a member function of the Engine class. */
    void Engine::Collect()
    {
        cout<<"Engine Collecting Data "<<ClassName<<endl;
    }
    
    /* This is a non-member function. It does not belong to a class.
    void Eat()
    {
        cout << "That was yummy!" << endl;
    }
    Here is the corrected code. Changed lines have been highlighted and comments are inline.
    Code:
    // WindowEngine.h
    #pragma once
    
    #include <string>
    #include "stdafx.h"
    #include <Windows.h> // System headers should be surrounded with <> rather than "".
    
    using namespace std;
    
    class Engine
    {
        public:
                Engine::Engine(void);
                Engine::Engine(string strClassName);
                Engine::~Engine(void);
        void    Engine::Collect();
        
    
        protected:
            string ClassName;
        
        private:
        
        // This function commented out. We don't need it.
        //BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
    
        // Declare this function static so it can be used as a callback.
        static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
    };
    Code:
    // WindowEngine.cpp
    #include "WindowEngine.h"
    #include <iostream> // Added header for cout, etc. 
    using namespace std;
    
    Engine::Engine(void)
    {
        ClassName = "Default";
        cout<<"Engine Constructor Default"<<endl;
    }
    
    Engine::Engine(string strClassName)
    {
        ClassName = strClassName;
        cout<<"Engine Constructor "<<strClassName<<endl;
        EnumWindows(EnumWindowsProc, (LPARAM) this);
    }
    
    Engine::~Engine(void)
    {
        cout<<"Engine Deconstructor "<<ClassName<<endl;
    }
    
    void Engine::Collect()
    {
        cout<<"Engine Collecting Data "<<ClassName<<endl;
    }
    
    //This function commented out, not needed...
    //BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
    //{
    //    return false;
    //}
    
    BOOL CALLBACK Engine::EnumWindowsProc(HWND hwnd, LPARAM lParam)
    {
        // This is a static member function so can be used as a callback...
        // Do something here...
         return TRUE;
    }

  8. #8
    Registered User
    Join Date
    Feb 2005
    Posts
    15
    Ok, so then the EnumWindows procedure is now going to call my EnumWindowsProc procedure and pass it the hWnd and LPARAM, correct? So I should put my code to get the classname and etc inside EnumWindowsProc?

    So when using API like this, you can't/don't declare it as a member function, and callbacks to anything must always be static, correct?

    Also, how would I call a function in the class from this static callback function?

    Thank you for your time, I'm just trying to learn how the API works in C++, I am wanting to get into Linux programming... any suggestions on books or websites as well?

    -Sean
    Last edited by coldfusion244; 02-22-2005 at 04:07 PM.

  9. #9
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    EnumWindowsProc is just a function pointer; it's typdef'd in winuser.h as:
    Code:
    typedef BOOL(CALLBACK *ENUMWINDOWSPROC)(HWND,LPARAM);
    CALLBACK is just a synonym for __stdcall. In other words, your EnumWindowsProc has to be of the same type and a c++ member function doesn't match that but a static member function does. A global function, preferably within a namespace, would also meet the type requirements.

    >>So I should put my code to get the classname and etc inside EnumWindowsProc?....how would I call a function in the class from this static callback function?<<

    Pass a pointer to the class (ie. this ) as the lParam, as previously demonstrated by anonytmouse, and then cast it back as an appropriate pointer which can be used normally to access c++ class members.
    Code:
    BOOL CALLBACK Engine::EnumWindowsProc(HWND hwnd, LPARAM lParam)
    {
      //convert lParam to Engine class pointer
      Engine *pEng=reinterpret_cast<Engine*>(lParam);
      //do stuff with it
       return TRUE;
    }
    >>I am wanting to get into Linux programming... any suggestions on books or websites as well?<<

    www.cprogramming.com, Linux programming board.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  10. #10
    Registered User
    Join Date
    Feb 2005
    Posts
    15
    Thank you for your help Ken. May I ask, are there any books that you may own (or have perused) that have excellent subject matter for C++? Maybe you know of a series, i.e. Beginner, intermediate, advanced; that takes the user throughout those stages. I am eager to learn as much as I can Ido not, however, have the materials (books, etc) to do so (since I don't know what is good/bad). Most of the simple things I do understand, but I would have never gotten the 'Engine *pEng=reinterpret_cast<Engine*>(lParam);'! I didn't even know it existed! I code for hobby and fun, nothing serious, but nonetheless want to become knowledgable on the subject. Thank you, again Ken and anony!

    -Sean

  11. #11
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    If you search, in particular, the c++ board for recommended texts I'm sure you'll find many interesting discussions and good advice. If, after doing so, you still feel you would like some extra guidance regarding good texts then I would suggest that you post a new topic in the General Discussions forum indicating that you've already searched the boards but are seeking more information.

    Good luck.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Window Image Capture
    By Lazy Student in forum Windows Programming
    Replies: 1
    Last Post: 02-17-2005, 08:06 AM