The Second Cut

Force BCB3 Open Dialog to be Resizeable

This technique is presented for use only in BCB3. It's completely unnecessary in later versions of BCB. Most users have a late enough version of commdlg.dll (Win98 or later) to present a resizeable Open Dialog. But because BCB3 was written before the details of a new flag for the Flags member of the OPENFILENAME API structure were published, it's not set by the VCL. And because the BCB Open Dialog is always hooked (to provide the various VCL events, like OnSelectionChange()), the default response of the .dll is to present a dialog without the sizing handle at the bottom right.

In case you're wondering, the "reason" for this behavior is the assumption that the user who hooked the dialog made modifications to it. It requires a lot of extra code to keep a dialog that has been modified looking "correct" after the user has resized it. Here's an example of such code.

Here's a BCB3 Project, consisting of a New Application's basic Form1, and a component derived using the New Component Wizard. Note that it is completely unnecessary to "Install" the component. This is not as easy as it should be for BCB users of any version. So it would be a distraction here.

For those familiar with component derivation, I've posted the BCB3 IDE-generated code in a weaker color. Only the code I typed appears in dark blue. I don't recommend that you cut and paste all of the code, although you'd probably get away with it. Rather, I've noted how all of the green code was generated, before I typed in the dark blue code. The test program below is inserted in the Form1 code generated by File|New Application.:


// --------------------------------------------------------------------------
#include 
#pragma hdrstop

#include "Unit1.h"
#include "ResizeableOpen.h"
// -------------------------------------------------------------------------- 
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
// --------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
TResizeableOpen * rso;

rso=new TResizeableOpen(this);

rso->Title="See if I'm resizeable!";
rso->InitialDir="C:\\";

rso->Execute();
Application->Terminate();
}
// --------------------------------------------------------------------------

Here's the derived component. The skeleton was generated by selecting File|New, and chosing "Component" from the list view that appears. The New Component Wizard has two fields that need to be filled in. The top combobox "Ancestor" should read TOpenDialog, and you should clear the next edit box. I chose to type in TResizeableOpen there for the name of the new component. After creating the component's code and header files, go back to Form1 and select File|Add Unit Header. There will be only one choice, "ResizeableOpen". Select it, so that the new component's header will be visible to the little test program, and click OK. (Note that the #include appears in the Form1 code above, where the IDE inserted it, because this step was taken before the code snapshots on this page were made!)

The .cpp file:

// --------------------------------------------------------------------------
#include 
#pragma hdrstop

#include "ResizeableOpen.h"
#pragma package(smart_init)
// --------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TResizeableOpen *)
{
	new TResizeableOpen(NULL);
}
// --------------------------------------------------------------------------
__fastcall TResizeableOpen::TResizeableOpen(TComponent* Owner)
	: TOpenDialog(Owner)
{
}
#define   OFN_ENABLESIZING      0x00800000

BOOL __fastcall TResizeableOpen::TaskModalDialog(void * DialogFunc,
    void* DialogData) // override Dialogs::TOpenDialog method
   {
   ((LPOPENFILENAMEA)DialogData)->Flags =
   ((LPOPENFILENAMEA)DialogData)->Flags | OFN_ENABLESIZING;
   ((LPOPENFILENAMEA)DialogData)->hInstance =
   (void*)FindClassHInstance(this->ClassType());
   return TCommonDialog::TaskModalDialog(DialogFunc, DialogData);
   }
// --------------------------------------------------------------------------
namespace Resizeableopen
{
	void __fastcall PACKAGE Register()
	{
		TComponentClass classes[1] = {__classid(TResizeableOpen)};
		RegisterComponents("Samples", classes, 0);
	}
}
// --------------------------------------------------------------------------

Note that in the "return" statement above, it's the base class's function that's called, not the immediate ancestor, TOpenDialog.

LPOPENFILENAMEA isn't as mysterious as it sounds. It's the VCL's way of avoiding conflicts with the Microsoft #defines in the Windows® header files. It corresponds to OPENFILENAME.

The resetting of the hInstance member is not necessary for this project, but it's how I learned about this technique. It's absolutely necessary when providing a Windows Dialog Template for use with a Common Dialog. The references go back to Delphi.

Now right-click on the component's .cpp file's tab and chose "Open Header File". Copy and paste the first line of the function definition, and make it into the declaration by adding a semicolon. It goes under "protected:", because it's available for overriding, but not accessible to the end-user.

The .h file:

// --------------------------------------------------------------------------
#ifndef ResizeableOpenH
#define ResizeableOpenH
// --------------------------------------------------------------------------
#include 
#include 
#include 
#include 
#include 
// --------------------------------------------------------------------------
class PACKAGE TResizeableOpen : public TOpenDialog
{
private:
protected:
        BOOL __fastcall TResizeableOpen::TaskModalDialog(void * DialogFunc,
            void* DialogData); // override Dialogs::TOpenDialog method
public:
	__fastcall TResizeableOpen(TComponent* Owner);
__published:
};
// --------------------------------------------------------------------------
#endif

Back to BCB Examples



Copyright © 2003 Timothy H. Buchman
Trademark notices     Privacy statement
Back to Home
 
Published: November 12, 2003
Modified: November 14, 2003