www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/07/26/17:15:39

From: Derek Harmon <derek AT ix DOT netcom DOT com>
Newsgroups: comp.lang.c,comp.os.msdos.djgpp
Subject: Re: Menus and mouse: how to tell what to do?
Date: Sun, 26 Jul 1998 16:28:51 -0400
Organization: ICGNetcom
Lines: 107
Message-ID: <35BB9183.C658F30@ix.netcom.com>
References: <35ba510b DOT 361228 AT news DOT unisys DOT com DOT br>
NNTP-Posting-Host: trn-nj2-12.ix.netcom.com
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Bruno Barberi Gnecco wrote:
> I'd like to know if it's possible to create and array of function names. For

	Yes, it is.  For the specific example of an array of names (strings)
and their associated functions such that you could perform a run-time lookup
based on string, see the oft-referred to FAQ Question 20.6.

> instance, let's say that a menu has 5 options; if I could just detect what is the
> chosen option (let's say, n), I could use the stored function name at the position
> n, instead of a long switch. Or maybe, a more clever approach to solve this menu

	Yes you can.  If you have five functions to handle each of the five
choices on the menu, and each of the five functions share a common prototype
(for example, returning an integer and taking no arguments) you could use
the following,

	int func1(void) {
		:
	}

	int func2(void) {
		:
	}
		:
		:
	int func5(void) {
		:
	}
		:
		:
	int getMenuChoice( const char *menu, int min_opt, int max_opt) {
		:
	}
		:
		:
	int main(int argc, char *argv[]) {
		int (*functions[5])(void) = { func1, func2, func3, func4, func5 };
		int return_value;
		:
		return_value = functions[ getMenuChoice( lpszMenu1, 1, 5) - 1]();
		/* Presumably do something with return_value. */	
		:
		return 0;		
	}

You can also initialize elements of a function pointer array as follows,

		functions[4] = func1;

instead of using an array initializer-list.

> What's the best way to tell the program: 'If you click here, do it', or 'If you
> choose this option, do that'??? To handle the mouse hot-spots, I thought about
> creating a struct like:
> struct mousespot {
>     char minx, maxx, miny, maxy;
>    ?function? // problem here
> }

	You can include a function pointer as a member of the struct, if
you defined them the same was as in the example I presented above,

	struct mousespot {
		char minx, maxx, miny, maxy;  /* see type note */
		int (*handleClick)(void);     /* see args note */
	}

	You can initialize this mousespot's handleClick function to a
function you declare with a matching (return int, takes void) prototype
with the following assignment (assuming hotspot is a variable declared
of type struct mousespot),

		hotspot.handleClick = func3;

	Then when in the course of your code you identify the mouse spot
in which the user clicked (getting the mouse click coordinates in some
manner appropriate to your platform) in the structure hotspot (of type
mousespot) as follows,

		hotspot.handleClick();

	Type Note.  Most modern day display resolutions cannot be
represented in one byte, these values may better be declared as ints.

	Args Note.  C doesn't have a convenient "this" construct, and
this usage doesn't grant whatever function is assigned to the handleClick
function pointer any special rights or knowledge of how it was called.
Hence you may have to declare it as taking a pointer to itself,

	The prototype of such a handler would be,

		int function_created_by_you( struct mousespot *pms);

	The declaration of the structure member function pointer is,

		int (*handleClick)(struct mousespot *pms);

	The initialization would be unchanged,

		hotspot.handleClick = function_created_by_you;

	The function invocation would become,

		hotspot.handleClick( &hotspot);


							Derek Harmon

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019