0

I have a Delphi application which has placed combobox. Recently after migrating to Win 7, notice behavior of combobox drop down is funny. It works fine as expected in XP where combobox dropdown from status bar rectange. But in Windows 7, Combobox drop down area is shown at top screen with flickering. One will have to keep the mouse button down to keep that shown, but that doesn't allow selecting any item.

Not sure if any other has experienced the same? Please advise what special handling need to be done in Win 7 for the combobox drop down to work perfectly when placed inside Status bar.

PS: Combobox placed on form behaves normally in Win7. Above cited behavior is only shown when combobox is placed inside status bar.

Appreciate your comments and/or suggestions.

Thanks.

Demo Code:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    ComboBox1: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure StatusBar1DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
      const Rect: TRect);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  Style, idx: Integer;
begin
    StatusBar1.Panels[0].Style := psOwnerDraw;
    ComboBox1.Parent := StatusBar1;
    Style := GetWindowLong(ComboBox1.Handle, GWL_EXSTYLE);
    Style := Style - WS_EX_STATICEDGE;
    SetWindowLong(ComboBox1.Handle, GWL_EXSTYLE, Style);
    for idx := 1 to 20 do
       ComboBox1.Items.Add(Format('Test Item %d',[idx]));
end;

procedure TForm1.StatusBar1DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
  const Rect: TRect);
begin
  if Panel = StatusBar1.Panels[0] then
    with ComboBox1 do
    begin
      Top := Rect.Top;
      Left := Rect.Left;
      Width := Rect.Right - Rect.Left - 5;
      Height := Rect.Bottom - Rect.Top - 10;
    end
end;

end.
  • Which Delphi version? – David Heffernan Oct 28 '13 at 17:45
  • 1
    Thanks David. It is Delphi XE - Update 1 – user2929116 Oct 28 '13 at 17:47
  • 1
    I cannot duplicate your problem (XE update1, W764-SP1). The only anomaly I observed was the difficulty convincing the IDE to let the statusbar parent the combobox. – Sertac Akyuz Oct 28 '13 at 17:59
  • Thanks Sertac. I created a demo App on W7 Pro 64bit-SP1. And it is showing the same behavior as cited above. Comments area is not allowing me to post all of the code. So updating my question with demo code. – user2929116 Oct 28 '13 at 18:11
  • @user - Well, no wonder I couldn't duplicate. OnDrawPanel is for drawing on the panel. Better position the combobox while you parent it in the statusbar. You know the ClientRect of the statusbar, and the width of the panel, use SB_GETBORDERS to get a sensible offset. – Sertac Akyuz Oct 28 '13 at 18:33
  • @SertacAkyuz Sorry not sure I understand your point. How are you suggesting to parent combobox? And how your suggestion is going to handle the resizing of statusbar as well as combobox? – user2929116 Oct 28 '13 at 18:39
  • 3
    @user - My suggestion is, don't try to modify the position of controls in a paint cycle. Position the combobox elsewhen. You can apply the initial position while you're parenting the combobox. If the box's position also depend on the statusbar's size, then you'd probably like to use the OnResize event of the statusbar. – Sertac Akyuz Oct 28 '13 at 18:49
  • You'll also need to cater for window recreation. Apply window styles in an overridden CreateParams. – David Heffernan Oct 28 '13 at 19:07
  • Thanks. But I don't understand what are the implication of applying the initial position of combobox during statusbar panel ondraw event. I am also not aware of any other way to embed controls inside statusbar without changing the drawstyle to psOwnerdarw as by default Statusbar panels are of psText type which only allows String. Also the question still remains on what extra steps need to be taken on Win7 for combobox to dropdown fine on Win7 when embedded inside statusbar, while the same code/approach/technique works in previous versions of windows. – user2929116 Oct 29 '13 at 09:35
  • @user - (1) You are running that code every time the panel draws. If nothing else, if the code really cause the position/size of the box to change, it will cause flicker. (2) I have no idea why are you trying to find another way of embedding. (3) Get your positions correct. You are setting the height of the control to something which it denies. In turn, you are trying to set it again and again since each time you set it causes yet another paint on the panel. Comment the call to set the height to see what I mean. I have no idea what you were doing on XP. (4) I'd repeat my previous comment here. – Sertac Akyuz Oct 29 '13 at 12:24
  • Thanks @SertacAkyuz. Really appreciate all your input/comments and suggestions. Removing the Height setting code, fixed the issue. I'm confused how the same was working fine in XP and previous versions :) Thanks again for all your help and insights. – user2929116 Oct 29 '13 at 17:29

1 Answers1

0

I think what you need is a stopper, so that the event handler knows when to stop drawing to the canvass or not to execute.

Or you can try this, it worked for me (delphi XE on Windows 8, to place combobox in statusbar, and change its behaviour to "drop up" items list).

procedure TForm1.StatusBar1DrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel; const Rect: TRect);
begin
  if Panel = StatusBar1.Panels[0] then
    with ComboBox1 do
    begin
      if Top = Rect.Top then Exit; //add this 
      Top := Rect.Top;
      Left := Rect.Left;
      Width := Rect.Right - Rect.Left - 5;
      Height := Rect.Bottom - Rect.Top - 10;
    end
end;
Beryllium
  • 12,808
  • 10
  • 56
  • 86