From: Doug Eleveld Newsgroups: comp.os.msdos.djgpp Subject: (no subject) Date: 18 Feb 1997 16:36:40 GMT Organization: Rijksuniversiteit Groningen Lines: 315 Message-ID: <5eclqo$huo@info.service.rug.nl> NNTP-Posting-Host: cmb18.med.rug.nl Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Can anyone help me make a C++ object for Allegro's Gui? I've got it basically working except for Allegro's do_dialog function doesn't seem to want to give the the focus when the object says it wants to have the focus. The code is pretty self explanatory and is strongly based on Allegro's EX13.C Thanks in advance, Doug Eleveld ------------------------CUT HERE------------------------ // Attempting to make a C++ object interface with the Allegro gui //routines // The do_dialog function does not want to give my object the focus // My dialog_object class only works when I give myself the focus // in the msg_gotfocus and msg_lostfocus member functions. // You can uncomment the functions and move the mouse over the object // to see the diffrence // For some reason, the do_dialog function doesn't want to do it for me // Anyone have any ideas what I am doing wrong here? // This code is extensively based on Allegros' ex13.c // // Trying to make a C++ gui object interface with the allegro do_dialog // So I removed a whole lot of stuff from ex13.c and added a // dialog_object // class. There is a box on the screen which should draw a diagonal // line when it has the focus and be clear without the focus #include #include #include "allegro.h" #include //----------------------------------------------------------------------- ----- class dialog_object :public DIALOG { private: // This function calls the right member functions when used // an allegro gui procedure static int dispatch_message_proc (int, DIALOG*, int); protected: // Ask about the object state bool has_focus (void) const { if(flags&D_GOTFOCUS) return true; return false; } bool has_mouse (void) const { if(flags&D_GOTMOUSE) return true; return false; } bool selected (void) const { if(flags&D_SELECTED) return true; return false; } // Message functions virtual void msg_start (void); virtual void msg_end (void); virtual void msg_draw (void); virtual void msg_click (void); virtual void msg_dclick (void); virtual void msg_key (void); virtual bool msg_char (const int); virtual bool msg_xchar (const int); virtual bool msg_wantfocus (void); virtual void msg_gotfocus (void); virtual void msg_lostfocus (void); virtual void msg_gotmouse (void); virtual void msg_lostmouse (void); virtual void msg_idle (void); virtual void msg_radio (const int); // Objects request redraw of dialog closings by setting // these variables and the dispatch_message_proc will // pass them along to the do_dialog procedure properly static bool request_redraw; static bool request_close; public: // Constructors and destructors dialog_object (const int, const int, const int, const int); virtual ~dialog_object (void); }; //---------------------------------------------------------------------- // Static variables and functions bool dialog_object::request_redraw = false; bool dialog_object::request_close = false; // The main dispatching function i.e. the interface between the C and C++ // object int dialog_object::dispatch_message_proc (int msg, DIALOG *d, int c) { // This conversion looks dangerous but actually it isnt since // it is a private function of the dialog_object and so it can only // be called from a dialog_object and so it can only be set as a // message procedure for the dialog through the dialog_object // So we know when this function is called, the DAILOG *d is // also a dialog_object and so we can use it to call the message // functions // for itself and the derived classes of dialog_object // dialog_object *object = (dialog_object*)(d->dp); // Convert the allegro message to a call of a member function switch(msg) { case(MSG_START): object->msg_start(); break; case(MSG_END): object->msg_end(); break; case(MSG_DRAW): object->msg_draw(); break; case(MSG_CLICK): object->msg_click(); break; case(MSG_DCLICK): object->msg_dclick(); break; case(MSG_KEY): object->msg_key(); break; case(MSG_CHAR): if(object->msg_char(c)==true) return D_USED_CHAR; case(MSG_XCHAR): if(object->msg_xchar(c)==true) return D_USED_CHAR; case(MSG_WANTFOCUS): if(object->msg_wantfocus()==true) return D_WANTFOCUS; //????????????????????????????????????????????????????????????????????? // Here is the part that I don't understand // The do_dialog function does not want to give my object the focus // Shouldn't the do_dialog function have given me the // focus // before calling this ? case(MSG_GOTFOCUS): // I think this assertion should fail but it doesn't !!!! assert(!((object->flags)&D_GOTFOCUS)); object->msg_gotfocus(); break; //?????????????????????????????????????????????????????????????????????? case(MSG_LOSTFOCUS): object->msg_lostfocus(); break; case(MSG_GOTMOUSE): object->msg_gotmouse(); break; case(MSG_LOSTMOUSE): object->msg_lostmouse(); break; case(MSG_IDLE): object->msg_idle(); break; case(MSG_RADIO): object->msg_radio(c); break; default: { // Just ignore an unknown message } } // Check if any of the functions asked for a redraw or a close of the // dialog if(dialog_object::request_redraw==true) { dialog_object::request_redraw = false; return D_REDRAW; } if(dialog_object::request_close==true) { dialog_object::request_close = false; return D_CLOSE; } return D_O_K; } //---------------------------------------------------------------------- // Constructor dialog_object::dialog_object (const int rx, const int ry, const int rw, const int rh) { // Set the dimensions x = rx; y = ry; w = rw; h = rh; // Set an all empty DIALOG key = 0; flags = 0; d1 = d2 = 0; // Quick setup of some colours fg = gui_fg_color; bg = gui_bg_color; // Setup the C++ message dispatching function proc = &dispatch_message_proc; // For C++ objects dp is the pointer to the internal dialog dp = this; } //-------------------------------------------------------------------- // Destructor dialog_object::~dialog_object (void) { } //---------------------------------------------------------------------- // Basic message passing functions // Initialization of the dialog void dialog_object::msg_start (void) { } // De-initialization of the dialog void dialog_object::msg_end (void) { } // Tell the object to draw itself void dialog_object::msg_draw (void) { rect(screen,x,y,x+w,y+h,255); if((flags)&D_GOTFOCUS) line(screen,x,y,x+w,y+h,255); else line(screen,x,y,x+w,y+h,0); } // Tell the object to deal with a mouse click void dialog_object::msg_click (void) { } // Tell the object to deal with a double click void dialog_object::msg_dclick (void) { } // Tell the object that a shortcut key was pressed void dialog_object::msg_key (void) { if(flags&D_EXIT) { request_close = true; } } // Tell the object that a key was pressed while it had the focus // This should return true if the key was used bool dialog_object::msg_char (const int) { return false; } // Tell the object that a key was pressed while it did noty have the focus // This should return true if the key was used bool dialog_object::msg_xchar (const int) { return false; } // Ask the object if they want the focus bool dialog_object::msg_wantfocus (void) { return true; } // ?????????????????????????????????????????????????????????????????? // My dialog_object class only works when I give myself the focus // in the msg_gotfocus and msg_lostfocus member functions. // For some reason, the do_dialog function doesn't want to do it for me // If you uncomment the stuff in the msg_gotfocus and msg_lostfocus // member function then it will work. Why doesn't Allegro do this for // me? // Anyone have any ideas what I am doing wrong here? // Tell the object that the got or lost the focus void dialog_object::msg_gotfocus (void) { /*flags|=D_GOTFOCUS; */ } void dialog_object::msg_lostfocus (void) { /*flags&=~D_GOTFOCUS;*/ } // ???????????????????????????????????????????????????????????????????? // Tell the object that they got or lost the mouse void dialog_object::msg_gotmouse (void) { } void dialog_object::msg_lostmouse (void) { } // Tell the object that the object manager is bored void dialog_object::msg_idle (void) { } // Deselect grouped radio buttons void dialog_object::msg_radio (const int) { } //---------------------------------------------------------------------- // Declare the dialog object dialog_object test_object = dialog_object(80,132,160,48); // A test dialog for the dialog object DIALOG the_dialog[] = { /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */ { d_clear_proc, 0, 0, 192, 172, 255, 0, 0, 0, 0, 0, NULL }, { d_text_proc, 80, 32, 512, 48, 255, 0, 0, 0, 0, 0, "There should be a line in the box when you move the mouse into it" }, (DIALOG)test_object, { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL } }; //----------------------------------------------------------------------- int main(void) { /* initialise everything */ allegro_init(); install_keyboard(); install_mouse(); install_timer(); set_gfx_mode(GFX_VESA1, 640, 480, 0, 0); set_pallete(desktop_pallete); /* do the dialog */ do_dialog(the_dialog, 2); exit(0); } //---------------------------------------------------------------------