communicating through callback

A

andthen

I'm using a windows library function which does not return anything useful
(EnumWindows... returns a BOOL), I give it a pointer to a callback function
and it sends the data I want to the callback function. My question is, what
is the best way to get that data into the initial function, which called the
library function? The only way I can think of is to have the callback
function modify a global variable and then have the initial function access
that. But that seems messy and I'm wondering if there is a better way. Any
ideas?
 
B

Bernhard

andthen said:
I'm using a windows library function which does not return anything useful
(EnumWindows... returns a BOOL), I give it a pointer to a callback function
and it sends the data I want to the callback function. My question is, what
is the best way to get that data into the initial function, which called the
library function? The only way I can think of is to have the callback
function modify a global variable and then have the initial function access
that. But that seems messy and I'm wondering if there is a better way. Any
ideas?

I think it depends on the information you like to get from the
EnumWindows. If you would like to process all the windows, do it in the
callback function. If you would like to search a special window handle,
you can send the window-handle by a user-defined message.
By the way, not all global variables are messy. if you label them, is
easy to know, which variable is global.

best regards
Bernhard
 
G

Guest

Hi!

I'm using a windows library function which does not return anything useful
(EnumWindows... returns a BOOL), I give it a pointer to a callback function
and it sends the data I want to the callback function. My question is, what
is the best way to get that data into the initial function,


struct WNDSTRUCT_t
{
HWND m_hFirst;
};

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
assert(lParam);
WNDSTRUCT_t* pWndStruct=(WNDSTRUCT_t*)lParam;
pWndStruct->m_hFirst=hWnd;
return FALSE;
}

void main(void)
{
WNDSTRUCT_t Result;
if(EnumWindows(EnumWindowsProc, &Result)) printf("First: %X\n", (unsigned long)Result.m_hFirst);
}


HTH,
V.
 
M

Malcolm

andthen said:
I'm using a windows library function which does not return anything
useful (EnumWindows... returns a BOOL), I give it a pointer to a
callback function and it sends the data I want to the callback function.
My question is, what is the best way to get that data into the initial
function, which called the library function? The only way I can think of
is to have the callback function modify a global variable and then have
the initial function access that. But that seems messy and I'm wondering
if there is a better way. Any ideas?
When you are specifying an interface involving callbacks, the callback
should always be passed a void * to avoid this problem. You then modify a
structure local to the top-level function. If the library provider has
neglected to do this, there is not much you can except to use a global.
 
A

andthen

Thanks for the help... I did not realize that the purpose of the second
parameter of EnumWindows was for a typecasted pointer. Using it as such
works fine.
 
J

Jack Klein

Hi!




struct WNDSTRUCT_t
{
HWND m_hFirst;
};

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)

In the absence of supporting macro definitions, the above is a nothing
but a syntax error in C.
{
assert(lParam);
WNDSTRUCT_t* pWndStruct=(WNDSTRUCT_t*)lParam;
pWndStruct->m_hFirst=hWnd;
return FALSE;
}

void main(void)
^^^^

Oh, you're not programming in C, although you might think that you
are. You're in the newsgroup. In C, main() returns int in a hosted
environment.

PS: The Windows API is not part of the C language or library and is
severely off-topic here.
 
M

Malcolm

[ example windows program snipped ]
PS: The Windows API is not part of the C language or library and is
severely off-topic here.
To clarify, the OP was on topic because he was asking how to use the C
language effectively given a certain API. The reply wasn't on topic, because
it posts a non-portable program whose only purpose was to illustrate how to
use the details of that API. Just mentioning Windows doesn't in itself
destroy topicality, though you should check to see whether your question
really is a C language question.
 
P

Peter Slootweg

andthen said:
I'm using a windows library function which does not return anything useful
(EnumWindows... returns a BOOL), I give it a pointer to a callback function
and it sends the data I want to the callback function. My question is, what
is the best way to get that data into the initial function, which called the
library function? The only way I can think of is to have the callback
function modify a global variable and then have the initial function access
that. But that seems messy and I'm wondering if there is a better way. Any
ideas?
the nice way to implement callbacks is to allow the caller to pass in a
context pointer that is then passed into the callback function

e.g.

/* from handle.h */
typedef unsigned long handle;
#define handleisvalid(h) (h!=0UL)
typedef int (*cbfunctype)(handle h, void * context);
int enumhandles(cbfunctype cbfunc, void * context);

/* from x.c */
#include "handle.h"
#include <stdio.h>
struct indata
{
int i;
};

struct outdata
{
int o;
};

struct cbcontextdata {
struct indata in;
struct outdata out;
};

int mycbfunc(handle h, void *context)
{
cbdata * pcbd = context;
pcbd->out.o += pcbd->in.i + pcbd->in.i ; /* or whatever else you want to
do with h */
return !0; /* 0 if you want to stop processing */
}

int main(void)
{
int rc;
cbdata cbd;
cbd.in.i = 1;
cbd.out.o = 0;
rc = enumhandles(mycbfunc,&cbd);
if (rc != 0)
{
printf("%d\n",cbd.out.o);
}
return 0;
}

/* from handle.c */
#include "handle.h"
int enumhandles(cbfunctype cbfunc, void * context)
{
handle somehandle;
int rc = 1;
somehandle = /* firsthandle() */ 100;
while(handleisvalid(somehandle) && ((*cbfunc)(somehandle,context) != 0))
somehandle = /* nexthandle() */ somehandle - 1;
return rc;
}

[OT]
EnumWindows has a context parameter of type LPARAM - which is large enough
to hold a void pointer.
e.g.
EnumWindows(mywinenumcallback,(LPARAM)(void *)&mycallbackdata);
IMHO They really should have done it as a LPVOID (void *).
[/OT]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top