I want you to try something before your users do. First, create a Windows shortcut to an application you've written with C++ Builder. Then, right-click on the shortcut, choose Properties from the speed menu, and select the Shortcut tab in the resulting dialog box. In the Run dropdown box, select either Minimized or Maximized, as shown in Figure A.
Figure A: Set the Run property to Minimized.
Now run your application using the shortcut. Did your application's main window appear minimized or maximized? No? Then read on. In this article, we'll explain why your application didn't appear in the proper state and how you can easily work around this problem.
Borland included the following obstacle in the VCL on purpose: Every VCL-based application is a hidden window. The VCL makes Windows, the operating system, think this hidden window--rather than your main form--is your application's main window.When a user minimizes your application, this hidden window is minimized and the VCL hides your main form. Your main form is never actually minimized. Borland has tried to ease your pain by including methods and events in the TApplication class such as Minimize() and OnMinimize. We'll use another event from Tapplication--OnRestore--in our code. Let's see how to use our workaround.
as part of the file dec97.zip; click the Source Code hyperlink.) To begin, create a new project with a single form named MinMaxForm. Add an OnCreate event named FormCreate() to the form, as shown in Listing A. FormCreate() will do nearly all the work.
Listing A: TMinMaxForm
//------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "Main.h"
//------------------------------------
#pragma resource "*.dfm"
TMinMaxForm *MinMaxForm;
//------------------------------------
__fastcall
TMinMaxForm::TMinMaxForm(TComponent*
Owner) : TForm(Owner)
{
Application->OnRestore = OnRestore;
}
//------------------------------------
void __fastcall
TMinMaxForm::FormCreate(TObject
*Sender)
{
int cmdShow = System::CmdShow;
if (cmdShow == SW_SHOWDEFAULT ||
cmdShow == SW_HIDE)
{
STARTUPINFO startupInfo;
GetStartupInfo(&startupInfo);
if (startupInfo.dwFlags &
STARTF_USESHOWWINDOW)
cmdShow =
startupInfo.wShowWindow;
}
if (cmdShow == SW_MINIMIZE ||
cmdShow == SW_SHOWMINIMIZED ||
cmdShow == SW_SHOWMINNOACTIVE)
{
::ShowWindow(
Application->Handle,
SW_HIDE);
::ShowWindow(
Application->Handle,
SW_MINIMIZE);
Application->ShowMainForm =
false;
}
else if (cmdShow == SW_MAXIMIZE ||
cmdShow == SW_SHOWMAXIMIZED)
WindowState = wsMaximized;
}
//------------------------------------
void __fastcall
TMinMaxForm::OnRestore(TObject
*Sender)
{
Visible = true;
}
//------------------------------------
First, you declare a cmdShow variable and set it equal to System::nCmdShow.
This should be the value passed into your program by Windows--but due to
Borland's bug, it will be SW_SHOWDEFAULT or SW_HIDE. You check the value here
so the program will still work when Borland fixes the bug.If cmdShow is
equal to SW_SHOWDEFAULT or SW_HIDE, the code checks the application's
STARTUPINFO structure. You fill in startupinfo--an instance of this
structure--by calling the Windows API function GetStartupInfo(). If the
STARTF_USESHOWWINDOW flag is set in startupinfo.dwFlags, then you set cmdShow
equal to the value in startupInfo.wShowWindow; otherwise, you ignore the
STARTUPINFO structure.
At this point in the code, you've worked around the bug. Now it's time to tackle the hidden window. If the value of cmdShow indicates that you need to minimize your window, the code hides the hidden window and then minimizes it. Next, you tell TApplication not to show the main form. This step is equivalent to setting the main form's Visible property to false.
Why do you need to hide the hidden window? Actually, the "hidden" window isn't hidden at all--it's visible, but its width and height are set to zero, so you can't see it! If you didn't hide it first, you'd see the Windows zoom animation when the window minimized.
If cmdShow indicates that you should maximize the main form, the code simply sets the WindowState property to wsMaximized. There's one final detail to address. Remember, if cmdShow has you minimize your main form, you're really minimizing the hidden window and hiding the main form. If you then try to restore the main form, the hidden window will be restored (and still invisible) but the main form won't be made visible. To make everything work as expected, create an OnRestore() function in TminMaxForm; in TminMaxForm's constructor, assign the function to Tapplication's OnRestore event. In the OnRestore() function, you simply make sure the main form's Visible property is set to true.
Your users will also expect your application to remember its size, position, and state between uses. In a future article, we'll show you how to enhance TMinMaxForm to do just this.