// radioSet1- // // This program demonstrates operations on a radio button, including // simulated button clicks, double clicks, showing and hiding radio buttons, // enabling and disabling radio buttons, moving radio buttons, and resizing // radio buttons. program radioSet1; #linker( "comdlg32.lib" ) #linker( "comctl32.lib" ) ?@NoDisplay := true; ?@NoStackAlign := true; #includeOnce( "stdlib.hhf" ) #includeOnce( "howl.hhf" ) const applicationName := "Radio Buttons #1"; formX := w.CW_USEDEFAULT; // Let Windows position this guy formY := w.CW_USEDEFAULT; formW := 600; formH := 600; static align( 4 ); bkgBrush_g :dword; bkgColor_g :dword; // Forward declarations for the onClick widgetProcs that we're going to // call when an event occurs. proc onClick1 :widgetProc; @forward; proc hideShowRadioButton :widgetProc; @forward; proc enableDisableRadioButton :widgetProc; @forward; proc moveRadioButton :widgetProc; @forward; proc resizeRadioButton :widgetProc; @forward; proc onDblClick :widgetProc; @forward; proc onQuit :widgetProc; @forward; // Here's the main form definition for the app: wForm( mainAppWindow ); var showState :boolean; b1Enabled :boolean; align(4); wRadioButton ( radioButton1, // Field name in mainWindow object "Radio Button #1 abc", // Caption for push button 0, // Style 10, // x position 10, // y position 125, // width 25, // height onClick1 // "on click" event handler ) wRadioButtonLT ( radioButton2, // Field name in mainWindow object "Radio Button #2 abc", // Caption for push button 0, // Style 10, // x position 70, // y position 125, // width 25, // height onClick1 // "on click" event handler ) wPushButton ( button2, // Field name in mainWindow object "Hide radio button 1", // Caption for push button 175, // x position 10, // y position 175, // width 25, // height hideShowRadioButton // initial "on click" event handler ) wPushButton ( button3, // Field name in mainWindow object "Disable radio button 1", // Caption for push button 175, // x position 40, // y position 175, // width 25, // height enableDisableRadioButton // initial "on click" event handler ) wPushButton ( button4, // Field name in mainWindow object "Move radio button 1", // Caption for push button 175, // x position 70, // y position 175, // width 25, // height moveRadioButton // initial "on click" event handler ) wPushButton ( button5, // Field name in mainWindow object "Resize radio buttons", // Caption for push button 175, // x position 100, // y position 175, // width 25, // height resizeRadioButton // initial "on click" event handler ) wPushButton ( button6, // Field name in mainWindow object "DblClick to Click", // Caption for push button 175, // x position 130, // y position 175, // width 25, // height NULL // no single click handler ) // Place a quit button in the lower-right-hand corner of the form: wPushButton ( quitButton, // Field name in mainWindow object "Quit", // Caption for push button 450, // x position 525, // y position 125, // width 25, // height onQuit // "on click" event handler ) endwForm // Must invoke the following macro to emit the code generated by // the wForm macro: mainAppWindow_implementation(); // The onDblClick widget proc will handle a double click on button6 // and simulate a single click on radio button1. proc onDblClick:widgetProc; begin onDblClick; mov( mainAppWindow.radioButton1, esi ); (type wRadioButton_t [esi]).click(); mov( mainAppWindow.radioButton2, esi ); (type wRadioButton_t [esi]).click(); end onDblClick; // The resizeRadioButton widget proc will resize radio button1 between widths 125 and 150. proc resizeRadioButton:widgetProc; begin resizeRadioButton; mov( mainAppWindow.radioButton1, esi ); (type wRadioButton_t [esi]).get_width(); if( eax = 125 ) then stdout.put( "Resizing radio button to width 150" nl ); (type wRadioButton_t [esi]).set_width( 150 ); mov( mainAppWindow.radioButton2, esi ); (type wRadioButton_t [esi]).set_width( 150 ); else stdout.put( "Resizing radio button to width 125" nl ); (type wRadioButton_t [esi]).set_width( 125 ); mov( mainAppWindow.radioButton2, esi ); (type wRadioButton_t [esi]).set_width( 125 ); endif; end resizeRadioButton; // The moveRadioButton widget proc will move radio button1 between y positions 10 and 40. proc moveRadioButton:widgetProc; begin moveRadioButton; mov( mainAppWindow.radioButton1, esi ); (type wRadioButton_t [esi]).get_y(); if( eax = 10 ) then stdout.put( "Moving radio button to y-position 40" nl ); (type wRadioButton_t [esi]).set_y( 40 ); else stdout.put( "Moving radio button to y-position 10" nl ); (type wRadioButton_t [esi]).set_y( 10 ); endif; end moveRadioButton; // The enableDisableRadioButton widget proc will hide and show radio button1. proc enableDisableRadioButton:widgetProc; begin enableDisableRadioButton; mov( thisPtr, esi ); if( mainAppWindow.b1Enabled ) then (type wRadioButton_t [esi]).set_text( "Enable radio button 1" ); mov( false, mainAppWindow.b1Enabled ); stdout.put( "Disabling button 1" nl ); mov( mainAppWindow.radioButton1, esi ); (type wRadioButton_t [esi]).disable(); else (type wRadioButton_t [esi]).set_text( "Disable radio button 1" ); mov( true, mainAppWindow.b1Enabled ); stdout.put( "Enabling button 1" nl ); mov( mainAppWindow.radioButton1, esi ); (type wRadioButton_t [esi]).enable(); endif; end enableDisableRadioButton; // The hideShowRadioButton widget proc will hide and show radio button1. proc hideShowRadioButton:widgetProc; begin hideShowRadioButton; mov( thisPtr, esi ); if( mainAppWindow.showState ) then (type wRadioButton_t [esi]).set_text( "Hide radio button 1" ); mov( false, mainAppWindow.showState ); stdout.put( "Showing button 1" nl ); mov( mainAppWindow.radioButton1, esi ); (type wRadioButton_t [esi]).show(); else (type wRadioButton_t [esi]).set_text( "Show radio button 1" ); mov( true, mainAppWindow.showState ); stdout.put( "Hiding button 1" nl ); mov( mainAppWindow.radioButton1, esi ); (type wRadioButton_t [esi]).hide(); endif; end hideShowRadioButton; // Here's the onClick handler for the radio button. Invert the state on each click. proc onClick1:widgetProc; begin onClick1; // Invert the dot in the radio button: mov( thisPtr, esi ); (type wRadioButton_t [esi]).get_check(); xor( 1, eax ); and( 1, eax ); (type wRadioButton_t [esi]).set_check( eax ); end onClick1; // Here's the onClick event handler for our quit button on the form. // This handler will simply quit the application: proc onQuit:widgetProc; begin onQuit; // Quit the app: w.PostQuitMessage( 0 ); end onQuit; // We'll use the main application form's onCreate method to initialize // the various buttons on the form. // // This could be done in appStart, but better to leave appStart mainly // as boilerplate code. Also, putting this code here allows us to use // "this" to access the mainAppWindow fields (a minor convenience). method mainAppWindow_t.onCreate; var thisPtr :dword; begin onCreate; mov( esi, thisPtr ); // Initialize the showState and enableDisableButton data fields: mov( false, this.showState ); mov( true, this.b1Enabled ); // Set up button6's onDblClick handler: mov( thisPtr, esi ); mov( this.button6, esi ); (type wPushButton_t [esi]).set_onDblClick( &onDblClick ); end onCreate; /////////////////////////////////////////////////////////////////////////////// // // // The following is mostly boilerplate code for all apps (about the only thing // you would change is the size of the main app's form) // // /////////////////////////////////////////////////////////////////////////////// // // When the main application window closes, we need to terminate the // application. This overridden method handles that situation. Notice the // override declaration for onClose in the wForm declaration given earlier. // Without that, mainAppWindow_t would default to using the wVisual_t.onClose // method (which does nothing). method mainAppWindow_t.onClose; begin onClose; // Tell the winmain main program that it's time to terminate. // Note that this message will (ultimately) cause the appTerminate // procedure to be called. w.PostQuitMessage( 0 ); end onClose; // When the application begins execution, the following procedure // is called. This procedure must create the main // application window in order to kick off the execution of the // GUI application: procedure appStart; begin appStart; push( esi ); // Create the main application window: w.GetSysColor( w.COLOR_MENU ); mov( eax, bkgColor_g ); w.CreateSolidBrush( eax ); mov( eax, bkgBrush_g ); mainAppWindow.create_mainAppWindow ( applicationName, // Window title w.WS_EX_CONTROLPARENT, // Need this to support TAB control selection w.WS_OVERLAPPEDWINDOW, // Style NULL, // No parent window formX, // x-coordinate for window. formY, // y-coordinate for window. formW, // Width formH, // Height bkgColor_g, // Background color true // Make visible on creation ); mov( esi, pmainAppWindow ); // Save pointer to main window object. pop( esi ); end appStart; // appTerminate- // // Called when the application is quitting, giving the app a chance // to clean up after itself. // // Note that this is called *after* the mainAppWindow_t.onClose method // executes (indeed, mainAppWindow_t.onClose, by posting the quit message, // is what actually causes the program to begin terminating, which leads // to the execution of this procedure). procedure appTerminate; begin appTerminate; // Clean up the main application's form. // Note that this will recursively clean up all the widgets on the form. mainAppWindow.destroy(); w.DeleteObject( bkgBrush_g ); end appTerminate; // appException- // // Gives the application the opportunity to clean up before // aborting when an unhandled exception comes along: procedure appException( theException:dword in eax ); begin appException; raise( eax ); end appException; // The main program for a HOWL application must simply // call the HowlMainApp procedure. begin radioSet1; HowlMainApp(); end radioSet1;