Log On
Embarcadero Home
Watch, Follow, &
Connect with Us
Share This
QualityCentral
Communities
Articles
Blogs
Resources
Downloads
Help
QualityCentral
Delphi-BCB
VCL
Standard Controls
TActionList
TButton
TCheckBox
TComboBox
TEdit
TGroupBox
TLabel
TListBox
TMainMenu
TMemo
TPanel
TPopupMenu
TRadioButton
TRadioGroup
TScrollBar
You are not logged in.
Help
Print
Public Report
Report From:
Delphi-BCB/VCL/Standard Controls/TPanel
[ Add a report in this area ]
Report #:
4304
Status:
Closed
Controls on a TPanel will not show focus rectangles under XP
Project:
Delphi
Build #:
4.453
Version:
7.0
Submitted By:
Jordan Russell
Report Type:
Basic functionality failure
Date Reported:
5/4/2003 10:36:53 AM
Severity:
Critical / Show Stopper
Last Updated:
3/20/2012 2:24:39 AM
Platform:
All versions
Internal Tracking #:
169373
Resolution:
Fixed
(Resolution Comments)
Resolved in Build:
:
9.0.1761.24408
Duplicate of:
None
Voting and Rating
Overall Rating:
(4 Total Ratings)
4.75 out of 5
Total Votes:
None
Description
This is a show-stopper issue for keyboard users:
Under Windows XP with TXPManifest, controls such as TCheckBox placed on a TPanel will not show a focus rectangle when focused, regardless of the "Hide underlines" setting in Display Properties, and regardless of whether the last input came from the keyboard.
TCheckBoxes placed inside a TGroupBox instead do not have this problem. So it seems to be an issue with TPanel.
Steps to Reproduce:
- Start Delphi 7 on Windows XP running the Windows XP theme (not the Classic theme)
- Drop a TXPManifest component
- Drop a TCheckBox component ("CheckBox1")
- Drop a TPanel component below
- Inside the TPanel, drop a TCheckBox component ("CheckBox2")
- Run
- Hold down Tab
- Notice that CheckBox1 gets a focus rectangle when focused, but CheckBox2 never does.
Workarounds
The responsibility for focus rectangle damages lays on an author of WM_PRINTCLIENT handler ;)
When checkbox processes CTLCOLORSTATIC message is requests its parent to draw background (DrawThemeParentBackground API). It calls Panel's WM_PRINTCLIENT, it calls TCustomPanel.Paint. In this handler Brush.Style is set to bsClear, this brush style is set to the DC passed inside (i.e. checkbox DC), and later when CTLCOLORSTATIC returns, focus rectangle is drawn using invalid brush resulting in no focus rectangle drawing :(
There are many possible workarounds in different places:
1) Ensure button.paint procedure to restore brush correctly. But it seems to be incorrect solution, because we should be allowed to do anything in .Paint handler ;) and also we can't guarantee any other 3rd-party panel-like control to do the same.
2) Save brush (and other DC state) before DrawThemeBackground and restore after it. It requires us to put this code in any location calling DrawThemeBackground. This is not elegant but will protect our DC from modification caused by any parent control (i.e. non-Delphi), that will contain ours.
3) Make sure that WM_PRINTCLIENT does not modify a state of the DC passed in.
The 3rd workaround is the following:
We have to add lines marked with (**) to the WMPrintClient handler.
procedure TWinControl.WMPrintClient(var Message: TWMPrintClient);
(**)
var
SaveIndex: Integer;
(**)
begin
with Message do
if Result <> 1 then
if ((Flags and PRF_CHECKVISIBLE) = 0) or Visible then
(**)
begin
SaveIndex := SaveDC(Message.DC);
(**)
PaintHandler(TWMPaint(Message));
(**)
RestoreDC(Message.DC,SaveIndex);
end
(**)
else
inherited
else
inherited;
end;
Now the focus rectangle is drawing fine ;) Also do not forget to add ';' after PaintHandler call
---------
The responsibility for focus rectangle damages lays on an author of WM_PRINTCLIENT handler ;)
When checkbox processes CTLCOLORSTATIC message is requests its parent to draw background (DrawThemeParentBackground API). It calls Panel's WM_PRINTCLIENT, it calls TCustomPanel.Paint. In this handler Brush.Style is set to bsClear, this brush style is set to the DC passed inside (i.e. checkbox DC), and later when CTLCOLORSTATIC returns, focus rectangle is drawn using invalid brush resulting in no focus rectangle drawing :(
There are many possible workarounds in different places:
1) Ensure button.paint procedure to restore brush correctly. But it seems to be incorrect solution, because we should be allowed to do anything in .Paint handler ;) and also we can't guarantee any other 3rd-party panel-like control to do the same.
2) Save brush (and other DC state) before DrawThemeBackground and restore after it. It requires us to put this code in any location calling DrawThemeBackground. This is not elegant but will protect our DC from modification caused by any parent control (i.e. non-Delphi), that will contain ours.
3) Make sure that WM_PRINTCLIENT does not modify a state of the DC passed in.
The 3rd workaround is the following:
We have to add lines marked with (**) to the WMPrintClient handler.
procedure TWinControl.WMPrintClient(var Message: TWMPrintClient);
(**)
var
SaveIndex: Integer;
(**)
begin
with Message do
if Result <> 1 then
if ((Flags and PRF_CHECKVISIBLE) = 0) or Visible then
(**)
begin
SaveIndex := SaveDC(Message.DC);
(**)
PaintHandler(TWMPaint(Message));
(**)
RestoreDC(Message.DC,SaveIndex);
end
(**)
else
inherited
else
inherited;
end;
Now the focus rectangle is drawing fine ;) Also do not forget to add ';' after PaintHandler call
Attachment
None
Comments
None
View Your Reports
Search
Server Response from: ETNACODE01
Developer Tools
Blackfish SQL
C++Builder
Delphi
FireMonkey
Prism
InterBase
JBuilder
J Optimizer
HTML5 Builder
3rdRail & TurboRuby
Database Tools
Change Manager
DBArtisan
DB Optimizer
ER/Studio
Performance Center
Rapid SQL
Technical Articles
Tutorials
White Papers
Press Releases
Newsletters
Add Content (GetPublished)
Audio
Audio & Video
Video
Bugs & Suggestions (QualityCentral)
Discussion Forums
Examples (CodeCentral)
Tags
Technology Partners
Downloads
Free Trials
Registered User Downloads
Beta Programs
Add Content (GetPublished)
Articles
Blogs
Bugs & Suggestions (QualityCentral)
Discussion Forums
Examples (CodeCentral)
Member Services
About
Connect with Us