|
WString appExt = ".exe";
WULong strEnd;
WRegistryKey regKey;
WString fileType, appPath, filePath = "http://www.yahoo.com";
int process_id;
WBool opened;
opened = regKey.Open( WRKeyClassesRoot, ".html" );
if( opened ) {
fileType = regKey.GetStringValue( NULL );
regKey.Close();
fileType += "\\shell\\open\\command";
opened = regKey.Open( WRKeyClassesRoot, fileType );
if( opened ) {
appPath = regKey.GetStringValue( NULL );
WString tempLeft = appPath.Left( 1 );
if( tempLeft == "\"" )
appPath.Chop( 1L );
WString tempRight = appPath.Right( 4 );
if( (tempRight != ".EXE") || (tempRight != ".exe") ) {
strEnd = appPath.Position( appExt, 0, true );
strEnd += 4;
appPath = appPath.Substring( 0, strEnd-0 );
}
process_id = spawnl( P_NOWAIT, appPath, "child",
filePath.GetText(), NULL );
regKey.Close();
}
}
Note that of course you would switch Yahoo's web site with the site of your choice. The code is basically just going into the registry and trying to find out the command line of the browser associated with .html files. Then it simply spawns a session of that browser with the desired site as a parameter. If you wanted to get really fancy, you could make a label with the site address (make sure it is blue so that the user instinctively knows it is clickable), and have a nice little hand mouse pointer associated with it... Just to give the user some clicking feedback, it would be nice if the text turned red as the mouse button is clicked down on it (and then back to blue as it's released)... This sounds like the perfect project for those of you want to get started with component building... So get cracking! :)
If you have ever used the masked text box to enter a date, you
have probably noticed the FDX will not work properly. Having the
masked textbox initialise to the current date can be a great time
saver for the user. All the user would have to do is TAB into
and out of the masked textbox to have it display the current date.
Yes that is great unless you are trying to use FDX. Following
the FDXUpdateControls back to the source reveals the masked text
box uses the inherited FDXIn() from WTextBox. This structure uses
GetText() which will not return the current date if nothing was
typed. This must be changed to GetText(0) for the single line
version of masked text box. To correct this, create a new class
that inherits from WMaskedTextBox and add the following public
methods for FDXIn and FDXOut. These will allow the FDX to fill
your structure without errors. Note that I set these up to fill
the FDX structure without the literals and expect the same if
you fill the structure manually. After you have added a masked
textbox on your form use the Object Inspector to set Advanced
Class property to refer to the new class you previously created.
WBool MyMaskedTB::FDXOut( void )
{
if( _fdxDataSource != NULL ) {
WString outputFormat = GetOutputFormat();
SetOutputFormat( "D:yyyymmdd" ); // Change this to your
desired format
WString newValue = GetText( 0 ); // This works
SetOutputFormat( outputFormat );
if( *_fdxDataSource != newValue ) {
SetFDXModified( true );
}
*_fdxDataSource = newValue;
}
return true;
}
WBool MyMaskedTB::FDXIn( void )
{
WBool acceptLiterals;
if( _fdxDataSource != NULL ) {
acceptLiterals = GetAcceptLiterals();
SetAcceptLiterals( false );
SetText( *_fdxDataSource );
return SetAcceptLiterals( acceptLiterals );
} else {
return true;
}
}
The Wizard component has predefined event-handlers for moving from one page to the next. However, if you choose to select your own sequence of pages based upon conditions established on previous pages, a few notes are in order. The safe way to set the page is with the GetWizard()->SetSelected() function - but not from the Next or Back cbClickEventHandlers. If you try to call SetSelected from any of the standard event handlers, the value of the current page may change after you read it. When the click event for the next or back buttons are clicked, the PageDeactivated event occurs. Using the methods described below require that the page to be skipped must have true returned in this event. I accomplished this by adding a SwitchAllowed method to each page and returning true if the conditions are met. For example: if( !Path1 ) return true;
It is necessary to use PostUserEvent( this, 0L ) in the next and back button click event-handlers. In the UserEventHandler the GetWizard()->SetSelected() can be used more reliably. The easiest way I found to manage the page selection (if you have a multiple page paths) is to set up WIntArrays to contain the page lists and define them in the Create event for the form. If you do not wish to skip the current page, return the current page. If you want the sequence of a path to be pages 0, 1, 3, 5, 9, 12, the return values must be as follows for the forward direction:
For back the following returns must be allowed
This is an example of the code required. In the Create event:
{// page lists
WIntArray First_F_PageList;
WIntArray First_B_PageList;
...
First_F_PageList.SetCount(12);
First_F_PageList[ 0] = 0;
First_F_PageList[ 1] = 1;
First_F_PageList[ 2] = 3;
First_F_PageList[ 3] = 3;
First_F_PageList[ 4] = 5;
First_F_PageList[ 6] = 9;
First_F_PageList[ 9] = 9;
First_F_PageList[10] = 12 ;
First_F_PageList[12] = 12 ;
First_B_PageList=First_F_PageList;
First_B_PageList[11] = 10;
First_B_PageList[ 8] = 5;
First_B_PageList[ 4] = 3;
First_B_PageList[ 2] = 1;
...
}// end create event
WBool FormName::cb_Next_Click( WObject * source, WEventData *
event )
{
// Direction is defined as public WBool in the FormName class
Direction = Forward; // Foward is #defined as true
PostUserEvent( this, 0L );
return( FALSE );
}
WBool FormName::FormName_User( WObject * source, WUserEventData
* event )
{
GetWizard()->SetSelected( GetNextPage(GetCurrentIndex()) );
return FALSE;
}
WInt FormName::GetNextPage( WInt CurrentPg )
{
FDXStruct * ThisFDX = FDXGetTarget();
WIntArray BPageList, FPageList; //backward and forward pagelists
switch (ThisFDX->PathType)
{ case 1: FPageList = First_F_PageList;
BPageList = First _B_PageList; // for reverse
direction
break;
case 2: FPageList = Second_F_PageList;
BPageList = Second_B_PageList;
break;
case ETC: FPageList = Etc_F_PageList;
BPageList = Etc_F_PageList;
break;
// default to all pages
default: FPageList = F_OTHER_PageList;
BPageList = F_OTHER_PageList;
}
return ( (Direction==Forward) ? FPageList[CurrentPg]:BPageList[CurrentPg]
);
}
If you like to keep your programs' style according to the Windows standard like I do, you have probably noticed that the default behaviour of tab controls in Power++ (from from version 1.0 to 2.0) is not quite right. Here I list the steps you need to take to mimic the proper behaviour. (If you want to test these out on a sample program, place a tab control on a form with two tabs, two text boxes on each tab form, one command button underneath the tab control, and all the forms Auto Ordered using the tab stop editor.)
if( !tabctrl->GetFocus() ) { WControl * firstControl = newTabForm->GetControl( 0 );
WModelessDialog * newTabForm =
(WModelessDialog*)tabctrl->GetWindow( event->newID
);
WASSERT( newTabForm != NULL );
if( firstControl != NULL ) firstControl->SetFocus();
}
The first if statement is needed because if a tab already does have focus, it is proper for the new tab to get focus as soon as the user clicks on it. Note that you might not want the first control on the tab page to get the focus (GetControl( 0 )). For example, if the first control is a group box, or a disabled control, you would want to send the focus to the next control.
After looking at some MFC docs, I found a solution to adding a textbox (or any other type of control) to a toolbar. I haven't tested this with a floating toolbar, but it seems to work with a static toolbar.
WToolbarItemHandle itemHandle; // specifies the separator style // the bitmapIndex is used to specify the width of the separator // Insert the button defined above to the right of the 2nd button // set the toolbar as the parent of the control // get the bounding rectangle of the separator button and assign
WToolbarItemInfo buttonInfo;
WRect buttonRect;
buttonInfo.style = WTBBSeparator;
// if it is not the standard width. This is used to create space
// for the foreign control
buttonInfo.bitmapIndex = 50;
// in the toolbar
itemHandle = toolbar->Add( buttonInfo, 2 );
textbox->SetParent( toolbar );
// it to the textbox
buttonRect = toolbar->GetRectangle( itemHandle );
textbox->SetRectangle( buttonRect );