{----------------------------------------------------------------------------- The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/MPL-1.1.html Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is: JvCtrlUtils.PAS, released May 8, 2000. The Initial Developer of the Original Code is Petr Vones (petr dott v att mujmail dott cz) Portions created by Petr Vones are Copyright (C) 2000 Petr Vones. Portions created by Microsoft are Copyright (C) 1998, 1999 Microsoft Corp. All Rights Reserved. Contributor(s): ______________________________________. Last Modified: May 10, 2000 Current Version: 0.50 You may retrieve the latest version of this file at the Project JEDI's JVCL home page, located at http://jvcl.sourceforge.net Known Issues: -----------------------------------------------------------------------------} {$I JVCL.INC} unit JvCtrlUtils; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, Menus, Math, JclBase, JclSysUtils, JclStrings; function IntToExtended(I: Integer): Extended; //------------------------------------------------------------------------------ // ToolBarMenu //------------------------------------------------------------------------------ procedure JvCreateToolBarMenu(AForm: TForm; AToolBar: TToolBar; AMenu: TMainMenu = nil); //------------------------------------------------------------------------------ // ListView functions //------------------------------------------------------------------------------ type PJvLVItemStateData = ^TJvLVItemStateData; TJvLVItemStateData = record Caption: string; Data: Pointer; Focused, Selected: Boolean; end; procedure JvListViewToStrings(ListView: TListView; Strings: TStrings; SelectedOnly: Boolean = False; Headers: Boolean = True); function JvListViewSafeSubItemString(Item: TListItem; SubItemIndex: Integer): string; procedure JvListViewSortClick(Column: TListColumn; AscendingSortImage: Integer = -1; DescendingSortImage: Integer = -1); procedure JvListViewCompare(ListView: TListView; Item1, Item2: TListItem; var Compare: Integer); procedure JvListViewSelectAll(ListView: TListView; Deselect: Boolean = False); function JvListViewSaveState(ListView: TListView): TJvLVItemStateData; function JvListViewRestoreState(ListView: TListView; Data: TJvLVItemStateData; MakeVisible: Boolean = True; FocusFirst: Boolean = False): Boolean; function JvListViewGetOrderedColumnIndex(Column: TListColumn): Integer; procedure JvListViewSetSystemImageList(ListView: TListView); //------------------------------------------------------------------------------ // MessageBox //------------------------------------------------------------------------------ function JvMessageBox(const Text, Caption: string; Flags: DWORD): Integer; overload; function JvMessageBox(const Text: string; Flags: DWORD): Integer; overload; implementation uses CommCtrl, ShellAPI; resourcestring RsNotForMdi = 'MDI forms are not allowed'; function IntToExtended(I: Integer): Extended; begin Result := I; end; //============================================================================== // ToolBarMenu //============================================================================== procedure JvCreateToolBarMenu(AForm: TForm; AToolBar: TToolBar; AMenu: TMainMenu); var I, TotalWidth: Integer; Button: TToolButton; begin if AForm.FormStyle = fsMDIForm then raise EJclError.CreateResRec(@RsNotForMdi); if AMenu = nil then AMenu := AForm.Menu; if AMenu = nil then Exit; with AToolBar do begin TotalWidth := BorderWidth; for I := ButtonCount - 1 downto 0 do Buttons[I].Free; ShowCaptions := True; end; with AMenu do for I := Items.Count - 1 downto 0 do begin Button := TToolButton.Create(AToolBar); Button.Parent := AToolBar; Button.AutoSize := True; Button.Caption := Items[I].Caption; Button.Grouped := True; Button.MenuItem := Items[I]; Inc(TotalWidth, Button.Width + AToolBar.BorderWidth); end; AToolBar.Width := TotalWidth; AForm.Menu := nil; end; //============================================================================== // ListView functions //============================================================================== procedure JvListViewToStrings(ListView: TListView; Strings: TStrings; SelectedOnly: Boolean; Headers: Boolean); var R, C: Integer; ColWidths: array of Word; S: string; procedure AddLine; begin Strings.Add(TrimRight(S)); end; function MakeCellStr(const Text: string; Index: Integer): string; begin with ListView.Columns[Index] do if Alignment = taLeftJustify then Result := StrPadRight(Text, ColWidths[Index] + 1) else Result := StrPadLeft(Text, ColWidths[Index]) + ' '; end; begin SetLength(S, 256); with ListView do begin SetLength(ColWidths, Columns.Count); if Headers then for C := 0 to Columns.Count - 1 do ColWidths[C] := Length(Trim(Columns[C].Caption)); for R := 0 to Items.Count - 1 do if not SelectedOnly or Items[R].Selected then begin ColWidths[0] := Max(ColWidths[0], Length(Trim(Items[R].Caption))); for C := 0 to Items[R].SubItems.Count - 1 do ColWidths[C + 1] := Max(ColWidths[C + 1], Length(Trim(Items[R].SubItems[C]))); end; Strings.BeginUpdate; try if Headers then with Columns do begin S := ''; for C := 0 to Count - 1 do S := S + MakeCellStr(Items[C].Caption, C); AddLine; S := ''; for C := 0 to Count - 1 do S := S + StringOfChar('-', ColWidths[C]) + ' '; AddLine; end; for R := 0 to Items.Count - 1 do if not SelectedOnly or Items[R].Selected then with Items[R] do begin S := MakeCellStr(Caption, 0); for C := 0 to Min(SubItems.Count, Columns.Count - 1) - 1 do S := S + MakeCellStr(SubItems[C], C + 1); AddLine; end; finally Strings.EndUpdate; end; end; end; function JvListViewSafeSubItemString(Item: TListItem; SubItemIndex: Integer): string; begin if Item.SubItems.Count > SubItemIndex then Result := Item.SubItems[SubItemIndex] else Result := '' end; procedure JvListViewSortClick(Column: TListColumn; AscendingSortImage: Integer; DescendingSortImage: Integer); var ListView: TListView; I: Integer; begin ListView := TListColumns(Column.Collection).Owner as TListView; ListView.Columns.BeginUpdate; try with ListView.Columns do for I := 0 to Count - 1 do Items[I].ImageIndex := -1; if ListView.Tag and $FF = Column.Index then ListView.Tag := ListView.Tag xor $100 else ListView.Tag := Column.Index; if ListView.Tag and $100 = 0 then Column.ImageIndex := AscendingSortImage else Column.ImageIndex := DescendingSortImage; finally ListView.Columns.EndUpdate; end; end; procedure JvListViewCompare(ListView: TListView; Item1, Item2: TListItem; var Compare: Integer); var ColIndex: Integer; function FmtStrToInt(S: string): Integer; var I: Integer; begin I := 1; while I <= Length(S) do if not (S[I] in ['0'..'9', '-']) then Delete(S, I, 1) else Inc(I); Result := StrToInt(S); end; begin with ListView do begin ColIndex := Tag and $FF - 1; if Columns[ColIndex + 1].Alignment = taLeftJustify then begin if ColIndex = -1 then Compare := AnsiCompareText(Item1.Caption, Item2.Caption) else Compare := AnsiCompareText(Item1.SubItems[ColIndex], Item2.SubItems[ColIndex]); end else begin if ColIndex = -1 then Compare := FmtStrToInt(Item1.Caption) - FmtStrToInt(Item2.Caption) else Compare := FmtStrToInt(Item1.SubItems[ColIndex]) - FmtStrToInt(Item2.SubItems[ColIndex]); end; if Tag and $100 <> 0 then Compare := -Compare; end; end; procedure JvListViewSelectAll(ListView: TListView; Deselect: Boolean); var I: Integer; H: THandle; Data: Integer; SaveOnSelectItem: TLVSelectItemEvent; begin with ListView do if MultiSelect then begin Items.BeginUpdate; SaveOnSelectItem := OnSelectItem; Screen.Cursor := crHourGlass; try H := Handle; OnSelectItem := nil; if Deselect then Data := 0 else Data := LVIS_SELECTED; for I := 0 to Items.Count - 1 do ListView_SetItemState(H, I, Data, LVIS_SELECTED); finally OnSelectItem := SaveOnSelectItem; Items.EndUpdate; Screen.Cursor := crDefault; end; end; end; function JvListViewSaveState(ListView: TListView): TJvLVItemStateData; var TempItem: TListItem; begin with Result do begin Focused := Assigned(ListView.ItemFocused); Selected := Assigned(ListView.Selected); if Focused then TempItem := ListView.ItemFocused else if Selected then TempItem := ListView.Selected else TempItem := nil; if TempItem <> nil then begin Caption := TempItem.Caption; Data := TempItem.Data; end else begin Caption := ''; Data := nil; end; end; end; function JvListViewRestoreState(ListView: TListView; Data: TJvLVItemStateData; MakeVisible: Boolean; FocusFirst: Boolean): Boolean; var TempItem: TListItem; begin with ListView do begin TempItem := FindCaption(0, Data.Caption, False, True, False); Result := TempItem <> nil; if Result then begin TempItem.Focused := Data.Focused; TempItem.Selected := Data.Selected; end else if FocusFirst and (Items.Count > 0) then begin TempItem := Items[0]; TempItem.Focused := True; TempItem.Selected := True; end; if MakeVisible and (TempItem <> nil) then TempItem.MakeVisible(True); end; end; function JvListViewGetOrderedColumnIndex(Column: TListColumn): Integer; var ColumnOrder: array of Integer; Columns: TListColumns; I: Integer; begin Result := -1; Columns := TListColumns(Column.Collection); SetLength(ColumnOrder, Columns.Count); ListView_GetColumnOrderArray(Columns.Owner.Handle, Columns.Count, PInteger(ColumnOrder)); for I := 0 to High(ColumnOrder) do if ColumnOrder[I] = Column.Index then begin Result := I; Break; end; end; procedure JvListViewSetSystemImageList(ListView: TListView); var FileInfo: TSHFileInfo; ImageListHandle: THandle; begin FillChar(FileInfo, Sizeof(FileInfo), #0); ImageListHandle := SHGetFileInfo('', 0, FileInfo, SizeOf(FileInfo), SHGFI_SYSICONINDEX or SHGFI_SMALLICON); SendMessage(ListView.Handle, LVM_SETIMAGELIST, LVSIL_SMALL, ImageListHandle); FillChar(FileInfo, Sizeof(FileInfo), #0); ImageListHandle := SHGetFileInfo('', 0, FileInfo, SizeOf(FileInfo), SHGFI_SYSICONINDEX or SHGFI_LARGEICON); SendMessage(ListView.Handle, LVM_SETIMAGELIST, LVSIL_NORMAL, ImageListHandle); end; //============================================================================== // MessageBox //============================================================================== function JvMessageBox(const Text, Caption: string; Flags: DWORD): Integer; begin with Application do Result := MessageBox(PChar(Text), PChar(Caption), Flags); end; function JvMessageBox(const Text: string; Flags: DWORD): Integer; begin with Application do Result := MessageBox(PChar(Text), PChar(Title), Flags); end; end.