[win32] - getting child controls from it's parent

Jun 30, 2014 at 6:21pm
i'm trying doing a class for getting the child parent controls:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class ChildControls
{
private:
    vector<HWND> childcontrols;
    UINT childcontrolsindex;
    HWND windowparent;

public:
    ChildControls(const HWND parent)
    {
        windowparent=parent;
        //EnumChildWindows(parent, EnumChildProc, 0);
    }

    UINT childcontrolscount()
    {
        return childcontrolsindex;
    }

    HWND GetHWND(UINT index)
    {
        EnumChildWindows( windowparent,
                              [this]( HWND hwnd, LPARAM lParam )
                              {
                                    this->childcontrols.push_back(hwnd);
                                    this->childcontrolsindex = this->childcontrols.size(); // TODO:
                                    return TRUE;
                              },
                              0);


        if(index>=childcontrolsindex)
            index=childcontrolsindex-1;
        return childcontrols[index];
    }
}ChildControls;

but i'm getting several errors with EnumChildWindows() function and when i close the class. can anyone tell me what i'm doing wrong?
Jul 1, 2014 at 1:18pm
but i'm getting several errors with EnumChildWindows() function and when i close the class.
What are this errors and what does it mean "close the class"?
Jul 1, 2014 at 5:00pm
The first problem is on the first and the last line. You cannot create instance of class ChildControls called ChildControls. What you are doing is equivalent to
ChildControls ChildControls; Also, you fail create instance of the class because contructor requires a paramater ( ChildControls(const HWND parent) )

Second, the callback function cannot be part of the class.

Try this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
BOOL CALLBACK EnumChildProc( HWND hwnd, LPARAM lParam );
class ChildControls
{
private:
    vector<HWND> childcontrols;
    UINT childcontrolsindex;
    HWND windowparent;
    friend BOOL EnumChildProc( HWND hwnd, LPARAM lParam );
public:
    ChildControls(const HWND parent)
    {
        windowparent=parent;
        //EnumChildWindows(parent, EnumChildProc, 0);
    }

    UINT childcontrolscount()
    {
        return childcontrolsindex;
    }

    HWND GetHWND(UINT index)
    {
        EnumChildWindows( windowparent,EnumChildProc,(LPARAM)this);


        if(index>=childcontrolsindex)
            index=childcontrolsindex-1;
        return childcontrols[index];
    }
};

BOOL EnumChildProc( HWND hwnd, LPARAM lParam )
{
    ChildControls *cc=(ChildControls *)lParam;
    
    cc->childcontrols.push_back(hwnd);
    cc->childcontrolsindex = cc->childcontrols.size(); // TODO:
    return TRUE;    
}

// ..somewhere in main
ChildControls cc(some_windows_handle)
Last edited on Jul 1, 2014 at 5:07pm
Jul 1, 2014 at 6:29pm
thanks for all.
but i continue confuse why i can't do these line(when i close the class)?

}ChildControls;
what i need is avoiding instances of the class ;)
Jul 2, 2014 at 9:24am
You can
}childControls(window_handle); but I doubt you'll have an open window handle by the time you create a class. You can do something like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class ChildControls
{
// ...
public:
    ChildControls()
    {
        windowparent=0;
    }
    ChildControls(const HWND parent)
    {
// ...

  void SetHWND(const HWND parent)
  {
     windowparent=parent;
  }
// ...
}childControls;

// in main

childControls.setHWND(window_handle);
// do stuff 
Jul 2, 2014 at 6:21pm
thanks for all.
need ask 1 thing: without the EnumChildProc() function, can i get the control(not child control) with index 0(normaly it's the 1st form created)?
Jul 2, 2014 at 6:33pm
i'm trying:
1
2
3
4
5
6
7
8
9
10
11
12
HWND WindowMain=NULL;

BOOL GetWindowMain( HWND hwnd, LPARAM lParam )
{
    WindowMain=hwnd;
    return false;
}

void GetMainWindow()
{
    EnumWindows(GetWindowMain,(LPARAM)0);
}

but i get 1 error on last argument :(
what i'm doing wrong?
(i only need find the 1st handle)
Last edited on Jul 2, 2014 at 6:34pm
Jul 3, 2014 at 8:47am
The callback function definition must be
BOOL CALLBACK GetWindowMain( HWND hwnd, LPARAM lParam )
Jul 3, 2014 at 5:53pm
thanks for correct me.
but i continue with errors:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
BOOL CALLBACK EnumOnceProc( HWND hwnd, LPARAM lParam );
class WMain
{
private:
    HWND windowparent=NULL;
    friend BOOL EnumOnceProc( HWND hwnd, LPARAM lParam );
public:

    WMain()
    {
        EnumWindows( EnumOnceProc,(LPARAM)this);
    }

    operator HWND()
    {
        return windowparent;
    }

}WindowMain;

BOOL CALLBACK EnumOnceProc( HWND hwnd, LPARAM lParam )
{
    WMain *cc=(WMain*)lParam;
    cc->windowparent=hwnd;
    return false;
}


heres how i use it:
1
2
if (WindowMain==hwnd)
                        MessageBox(NULL,"they match", "hi",MB_OK);

the hwnd is from window main procedure.
why that message isn't activated?
the EnumWindows() is for the application? or for the Operate System?
Jul 4, 2014 at 5:11pm
I am not sure what you want to do. Do you want to check whether the first window handle returned by EnumWindows is a handle of your application? If so, then it might not always be true, because the topmost window can be taskbar or some hidden window ( http://stackoverflow.com/questions/295996/is-the-order-in-which-handles-are-returned-by-enumwindows-meaningful?answertab=votes#tab-top )
Jul 6, 2014 at 3:43pm
Null just see these function:
1
2
3
4
5
6
7
8
BOOL EnumChildProc( HWND hwnd, LPARAM lParam )
{
    ChildControls *cc=(ChildControls *)lParam;
    
    cc->childcontrols.push_back(hwnd);
    cc->childcontrolsindex = cc->childcontrols.size(); // TODO:
    return TRUE;    
}

you told me for pass the 'this' for EnumWindows() function. and then i can use that way for catch the pointer.
i did the same thing for windows procedure, but don't works :(
when i create the control(CreateWindowEx()) i send the 'this' on last parameter and in window procedure i do:
form *inst = (form*)lParam;
but by some reason i only get NULL... why?
Jul 8, 2014 at 10:05am
The pointer is passed to your window procedure only once to WM_CREATE message. You must handle the WM_CREATE message, and save the pointer.
1
2
3
4
5
6
7
8
9
// in window procedure
        case WM_CREATE:
         {
          CREATESTRUCT *cs=(CREATESTRUCT*)lParam;
          form *inst=(form*)cs->lpCreateParams; // this value is equal to the last parameter of CreateWindoiwEx

          SetWindowLongPtr(hwnd,GWL_USERDATA,(LONG_PTR)inst); // save it for later use
          return 0;
         }

To get the pointer again, use GetwindowLongPtr:
1
2
// somewhere in window porocedure, when you need it
form *inst=(form*)GetWindowLongPtr(hwnd,GWL_USERDATA);


WM_CREATE: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632619(v=vs.85).aspx
CREATESTRUCT: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632603(v=vs.85).aspx
SetWindowLongPtr: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644898(v=vs.85).aspx
Jul 8, 2014 at 7:04pm
i'm sorry NULL :(
but by some reason, that code don't works :(
it's because i use Code Blocks IDE with GNU compiler?
Jul 9, 2014 at 5:03pm
Can you post full code?
Jul 9, 2014 at 9:25pm
heres the entire code: http://codepad.org/SrOIpP6t
(sorry... the class is to big for put here :( )
by some reason i can't get the form instance pointer :(
Jul 10, 2014 at 9:56am
I quickly looked to your code and I saw that you mixed some class and window procedure variables. Your wm_ncreate should be
1
2
3
4
5
6
7
8
9
            case WM_NCCREATE:
            {
                CREATESTRUCT *p = (CREATESTRUCT *)lParam;
                inst = (form *)p->lpCreateParams;
                SetWindowLongPtr(HandleWindow, GWLP_USERDATA, (LONG_PTR)inst); // notice HandleWindow
                inst->hwnd =  HandleWindow;
                if (inst==NULL)
                     inst = (form *)GetWindowLongPtr( HandleWindow, GWLP_USERDATA);
            }
Jul 10, 2014 at 7:34pm
after execute the form isn't showed and then i get these ouptup message:
"Process terminated with status -1073741819 (0 minutes, 9 seconds)"
i don't know what means :(
Topic archived. No new replies allowed.