I have a Delphi problem which I could use a hand on...
In the main form of my application I have a status bar, which has 3 panels:
[ general information (hints etc.) ][ some text ][ icon, some text ]
It also has a TMainMenu component which is set up something like
File Edit ...
New
Save
Open
...
I set for panel 2 (the last one) Style=psOwnerDraw, and in OnDrawPanel I
paint, on the panel, the icon and the text (which is determined when the
application launches).
Nothing complicated so far, and this worked fine for a couple of weeks, when
suddenly it ceased working. Instead of icon+text, it now paints on the panel
the caption of the first menuitem in the main menu in the application (text
"New"), and no icon! I've debugged the code about gazillion times, and the
OnDrawPanel code gets executed, the icon is set right and the string
variable which should be drawn is ok. If I force redraw on the form (e.g. by
dragging off screen and onscreen again) It sometimes work, sometimes nothing
changes, sometimes part of the right icon+text is drawn.
This doesn't seem to happen on other computers near me, only the one I'm
working on.
Any tips would be greatly appreciated.
I'm using Delphi 4.0 SP3 on a NT 4.0 machine with SP4.
--
Jon G. Stefansson
TM-Software
http://www.tm-soft.com/
Jón G. Stefánsson <jo...@tolvumyndir.is> skrev i artiklen
<7p0ofi$nqh$1...@haukur.skyggnir.is>...
I have the exact same problem. I've tested my app on several machines
including Windows 98 with IE5 and it works on every machine EXCEPT NT 4.0.
I'm also at SP4 with IE5. I've searched newsgroups and seen other people
having this problem, but no solution.
I'm going to have to remove my psOwnerDraw panel if I can't fix this.
Any help appreciated.
Carole Moore
Clemson University, Clemson, SC USA
maybe we'll be of more help if you send the code that paints the icon
and the text.
bye.
I saw the hint on large strings, I tried it out but it was of no success.
The code I use to draw on the statusbar is here
procedure TfrmMain.sbMainDrawPanel(StatusBar: TStatusBar;
Panel: TStatusPanel; const Rect: TRect);
var
thePic: integer;
begin
thePic := getStatusbarPic;
{ Note: thePic contains number of the picture to paint, and
it's always right, I've checked }
if Panel=sbMain.Panels[2] then begin
imlStatusBar.Draw(sbMain.Canvas, Rect.Left+1, Rect.Top, thePic);
sbMain.Canvas.TextOut(Rect.left + 18, Rect.top + 1, theUser);
{ theUser is a property, returning the currently logged
on user, e.g. 'John Smith'. It's always right too. }
end;
end;
(Part of) the problem seems to be that this procedure isn't even called when
the application updates the statusbar all the time.
Thanks,
(the still confused)
>....
> The code I use to draw on the statusbar is here
>
> procedure TfrmMain.sbMainDrawPanel(StatusBar: TStatusBar;
> Panel: TStatusPanel; const Rect: TRect);
> var
> thePic: integer;
> begin
> thePic := getStatusbarPic;
> { Note: thePic contains number of the picture to paint, and
> it's always right, I've checked }
> if Panel=sbMain.Panels[2] then begin
> imlStatusBar.Draw(sbMain.Canvas, Rect.Left+1, Rect.Top, thePic);
> sbMain.Canvas.TextOut(Rect.left + 18, Rect.top + 1, theUser);
> { theUser is a property, returning the currently logged
> on user, e.g. 'John Smith'. It's always right too. }
> end;
> end;
I can't see anything wrong with this. I even tried to reproduce your
error by setting up a statusbar and a 'main menu' as the one you told
about. Everything worked fine.
I have some questions/comments:
Why check for Panel = sbMain.Panels[2]? If you only want to paint the
third panel then only set that panel to psOwnerDraw and leave the rest
of the panels (on the status bar) as psText. Then your procedure will
only be called when drawing this panel.
The sbMain seems to be your status bar and
sbMain.Canvas.TextOut(Rect.left + 18, Rect.top + 1, theUser) is probaly
OK, but consider using the StatusBar parameter that Delphi provides:
StatusBar.Canvas.TextOut(Rect.left + 18, Rect.top + 1, theUser)
It will give 'cleaner' code (and you won't have to change the code even
if you change the name of the statusbar).
Are you completely sure about the User Name? If you use the GetUserName
API call to get the user name then remember that it expects a PChar for
which there is allocated the necersary memory. The following works for
me:
var
Size : DWORD;
Buffer : Array[0..128] Of Char;
begin
Size:=128;
Buffer:='';
GetUserName(@Buffer,Size);
....
// do something with the user name.....
end;
Regards
Nicolai Buch-Andersen
ni...@mip.sdu.dk
I do not have a solution but I have made some progress in tracing the
cause. Basically the WM_DRAW_ITEM message for any owner draw status
bar panels (except Panel 1) is not being sent to the status bar panel.
Have a look at the source code for TCustomForm.WndProc in the forms
unit of the D4 VCL source. The code in this routine has changed
considerably from the D3 version. In particular, on receipt of a
WM_DRAW_ITEM message, the code casts the lparam to a PDrawItemStruct
and checks for CtlType of ODT_MENU. If this is true it then explicitly
draws a menu, rather than sending on the message to the control.
In the cases where the menu text is being drawn on the status bar,
CtlType=ODT_MENU, and the TMenuItem gets drawn instead. Now clearly
CtlType should not be ODT_MENU, and it is not for the first panel,
only for all subsequent ones. Something is wrongly setting, or failing
to set the lparam for the message.
>Jón G. Stefánsson <jo...@tolvumyndir.is> skrev i artiklen
><7p0ofi$nqh$1...@haukur.skyggnir.is>...
>> Hi all.
>>
>> I have a Delphi problem which I could use a hand on...
>>
>> In the main form of my application I have a status bar, which has 3
>panels:
>>
>> [ general information (hints etc.) ][ some text ][ icon, some text
> ]
>>
>> It also has a TMainMenu component which is set up something like
>>
>> File Edit ...
>> New
>> Save
>> Open
>> ...
>>
>> I set for panel 2 (the last one) Style=psOwnerDraw, and in OnDrawPanel I
>> paint, on the panel, the icon and the text (which is determined when the
>> application launches).
>>
>> Nothing complicated so far, and this worked fine for a couple of weeks,
>when
>> suddenly it ceased working. Instead of icon+text, it now paints on the
>panel
>> the caption of the first menuitem in the main menu in the application
>(text
>> "New"), and no icon! I've debugged the code about gazillion times, and
>the
>> OnDrawPanel code gets executed, the icon is set right and the string
>> variable which should be drawn is ok. If I force redraw on the form (e.g.
>by
>> dragging off screen and onscreen again) It sometimes work, sometimes
>nothing
>> changes, sometimes part of the right icon+text is drawn.
>>
>> This doesn't seem to happen on other computers near me, only the one I'm
>> working on.
>>
>> Any tips would be greatly appreciated.
>>
>> I'm using Delphi 4.0 SP3 on a NT 4.0 machine with SP4.
>>
>> --