I have been trying to write some owner-draw procedures for a TListView in Delphi. Specifically, I need to draw some small bitmaps in the vsReport style. I thought this would be easy. So I used the OnCustomDrawSubItem event and all seemed fine until I started changing the width of the columns during run-time. The problem was that ‘column.width’ was not being updated during the dragging and the result was a mess. After looking into the source code of the ComCtrls unit I decided to write a custom control that would update the column widths properly. Again, I thought this would be easy. I spent almost all day trying to figure out why things were not working. Finally I discovered this blog entry: http://thomasfreudenberg.com/blog/comments/352.aspx.
It seems that Microsoft has changed the notification for TListView and HDN_TRACK may not work. So, if you are having the same problems, here is my complete solution. It emulates a OnColumnTrack event (similar to the OnSectionTrack event of THeaderControl) and uses both HDN_TRACK and HDN_ITEMCHANGING to detect column changes.
This goes in the interface section of your unit:
type
TdhColumnTrackEvent = procedure(Sender: TCustomListview; Column: TListColumn; Width: Integer; State: TSectionTrackState) of object;
TdhListView = class(TListview)
private
FColumnTrackEvent: TdhColumnTrackEvent;
protected
procedure WMNotify(var Msg: TWMNotify); message WM_NOTIFY;
published
property OnColumnTrack: TdhColumnTrackEvent read FColumnTrackEvent write FColumnTrackEvent;
end;
This goes in the implementation section:
procedure TdhListView.WMNotify(var Msg: TWMNotify);
var
TrackState: TSectionTrackState;
aColumn: TListColumn;
begin
inherited;
with Msg do
case NMHdr^.code of
HDN_BEGINTRACK, HDN_ENDTRACK, HDN_TRACK, HDN_ITEMCHANGING:
begin
case NMHdr^.code of
HDN_BEGINTRACK: TrackState := tsTrackBegin;
HDN_ENDTRACK: TrackState := tsTrackEnd;
else
TrackState := tsTrackMove;
end;
with PHDNotify(Pointer(NMHdr))^, PItem^ do
if ((Mask and HDI_WIDTH) <> 0) then
begin
aColumn := Columns[Item];
if Assigned(FColumnTrackEvent) then FColumnTrackEvent(self, aColumn, cxy, TrackState);
end;
end;
end;
end;
Tuesday, August 29, 2006
Vienna again
It has been along time since I updated this blog. It seems that I have so many things to do, there is hardly any time left. Of course, it is always a matter of priorities, so you can figure how high this blog is on my list. Anyway, I was in Vienna in July, two times during the same month. Very hot weather. Vienna is a great city. For chocolates I recommend ‘Xokolat’, at Freyung 2 (Tel. 5354363). A large selection and not too expensive. I tried a 100% for the first time and I definitely do not recommend it; too bitter. I threw most of it away. However, the regular ones were excellent. The ‘Queen of Finland’ was kind enough to bring me some Fazer, which was very much appreciated. I guess we will see each other again in Berlin.
Subscribe to:
Posts (Atom)