/jcl/source/vcl/JclOpenDialogFavorites.pas
Pascal | 575 lines | 440 code | 53 blank | 82 comment | 31 complexity | 3a65015a381533f3d963377ed634679b MD5 | raw file
Possible License(s): BSD-3-Clause
1{**************************************************************************************************} 2{ } 3{ Project JEDI Code Library (JCL) } 4{ } 5{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); } 6{ you may not use this file except in compliance with the License. You may obtain a copy of the } 7{ License at http://www.mozilla.org/MPL/ } 8{ } 9{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF } 10{ ANY KIND, either express or implied. See the License for the specific language governing rights } 11{ and limitations under the License. } 12{ } 13{ The Original Code is OpenDlgFavAdapter.pas. } 14{ } 15{ The Initial Developer of the Original Code is Petr Vones. } 16{ Portions created by Petr Vones are Copyright (C) Petr Vones. All rights reserved. } 17{ } 18{ Contributor(s): } 19{ Salvatore Besso } 20{ Florent Ouchet (move to JCL runtime) } 21{ } 22{**************************************************************************************************} 23{ } 24{ Last modified: $Date:: $ } 25{ Revision: $Rev:: $ } 26{ Author: $Author:: $ } 27{ } 28{**************************************************************************************************} 29 30unit JclOpenDialogFavorites; 31 32interface 33 34{$I jcl.inc} 35 36uses 37 {$IFDEF HAS_UNITSCOPE} 38 Winapi.Windows, Winapi.Messages, Winapi.ShlObj, System.Classes, System.SysUtils, Vcl.Controls, Vcl.StdCtrls, Vcl.ExtCtrls, 39 {$ELSE ~HAS_UNITSCOPE} 40 Windows, Messages, ShlObj, Classes, SysUtils, Controls, StdCtrls, ExtCtrls, 41 {$ENDIF ~HAS_UNITSCOPE} 42 {$IFDEF UNITVERSIONING} 43 JclUnitVersioning, 44 {$ENDIF UNITVERSIONING} 45 JclPeImage, JclWin32, 46 JclOpenDialogHooks; 47 48// old-style open dialogs are supported by all versions of Delphi 49{$DEFINE OLDSTYLE} 50 51// new-style file dialogs are supported by Delphi 2007 and newer 52// it is disabled in D2007, because the D2006 RTL does not support it at all 53{$IFDEF RTL200_UP} 54{$DEFINE NEWSTYLE} 55{$ENDIF RTL200_UP} 56 57type 58 {$NODEFINE TJclOpenDialogFavoritesHook} // IFileDialogCustomize is badly emitted 59 TJclOpenDialogFavoritesHook = class (TJclOpenDialogHook{$IFDEF NEWSTYLE}, IFileDialogControlEvents, IFileDialogEvents, IInterface{$ENDIF}) 60 private 61 FFavoriteFolders: TStrings; 62 FTextAdd: string; 63 FTextDelete: string; 64 FTextVirtual: string; 65 {$IFDEF OLDSTYLE} 66 private 67 FFavoriteComboBox: TComboBox; 68 FFavoriteStaticText: TStaticText; 69 FFavoritePanel: TPanel; 70 procedure FavoriteComboBoxClick(Sender: TObject); 71 protected 72 procedure DialogAdjustControlPos; override; 73 procedure DialogFolderChange; override; 74 procedure DialogShow; override; 75 procedure DialogClose; override; 76 {$ENDIF OLDSTYLE} 77 {$IFDEF NEWSTYLE} 78 private 79 FComboboxCount: Integer; 80 FComboboxListItem, 81 FComboboxAddItem, 82 FComboboxDeleteItem, 83 FComboboxVirtualItem: Boolean; 84 FTextList: string; 85 procedure FileDialogCleanCombobox(const AFileDialogCustomize: IFileDialogCustomize); 86 procedure FileDialogFillCombobox(const AFileDialogCustomize: IFileDialogCustomize; ListItem, AddItem, DeleteItem, VirtualItem: Boolean); 87 protected 88 procedure FileDialogCreate(const AFileDialog: IFileDialog); override; 89 public 90 { IInterface } 91 function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; 92 function _AddRef: Integer; stdcall; 93 function _Release: Integer; stdcall; 94 public 95 { IFileDialogEvents } 96 function OnFileOk(const pfd: IFileDialog): HResult; stdcall; 97 function OnFolderChanging(const pfd: IFileDialog; 98 const psiFolder: IShellItem): HResult; stdcall; 99 function OnFolderChange(const pfd: IFileDialog): HResult; stdcall; 100 function OnSelectionChange(const pfd: IFileDialog): HResult; stdcall; 101 function OnShareViolation(const pfd: IFileDialog; const psi: IShellItem; 102 out pResponse: DWORD): HResult; stdcall; 103 function OnTypeChange(const pfd: IFileDialog): HResult; stdcall; 104 function OnOverwrite(const pfd: IFileDialog; const psi: IShellItem; 105 out pResponse: DWORD): HResult; stdcall; 106 public 107 { IFileDialogControlEvents } 108 function OnItemSelected(const pfdc: IFileDialogCustomize; dwIDCtl: DWORD; 109 dwIDItem: DWORD): HResult; stdcall; 110 function OnButtonClicked(const pfdc: IFileDialogCustomize; 111 dwIDCtl: DWORD): HResult; stdcall; 112 function OnCheckButtonToggled(const pfdc: IFileDialogCustomize; 113 dwIDCtl: DWORD; bChecked: BOOL): HResult; stdcall; 114 function OnControlActivating(const pfdc: IFileDialogCustomize; 115 dwIDCtl: DWORD): HResult; stdcall; 116 {$ENDIF NEWSTYLE} 117 public 118 constructor Create; override; 119 destructor Destroy; override; 120 procedure LoadFavorites(const FileName: string); 121 property FavoriteFolders: TStrings read FFavoriteFolders; 122 end; 123 124{$NODEFINE InitializeOpenDialogFavorites} 125function InitializeOpenDialogFavorites: TJclOpenDialogFavoritesHook; 126{$NODEFINE FinalizeOpenDialogFavorites} 127procedure FinalizeOpenDialogFavorites; 128 129{$IFDEF UNITVERSIONING} 130const 131 UnitVersioning: TUnitVersionInfo = ( 132 RCSfile: '$URL$'; 133 Revision: '$Revision$'; 134 Date: '$Date$'; 135 LogPath: 'JCL\source\vcl'; 136 Extra: ''; 137 Data: nil 138 ); 139{$ENDIF UNITVERSIONING} 140 141implementation 142 143uses 144 {$IFDEF HAS_UNITSCOPE} 145 Winapi.CommDlg, Winapi.Dlgs, 146 {$ELSE ~HAS_UNITSCOPE} 147 CommDlg, Dlgs, 148 {$ENDIF ~HAS_UNITSCOPE} 149 JclBase, JclFileUtils, JclStrings, JclSysInfo, JclSysUtils, JclVclResources; 150 151{$IFDEF NEWSTYLE} 152const 153 CTRLID_COMBOBOX = $2346; 154 ITEMID_LIST = $FFFF; 155 ITEMID_ADD = $FFFE; 156 ITEMID_DELETE = $FFFD; 157 ITEMID_VIRTUAL = $FFFC; 158{$ENDIF NEWSTYLE} 159 160function InitializeOpenDialogFavorites: TJclOpenDialogFavoritesHook; 161begin 162 Result := InitializeOpenDialogHook(TJclOpenDialogFavoritesHook) as TJclOpenDialogFavoritesHook; 163end; 164 165procedure FinalizeOpenDialogFavorites; 166begin 167 FinalizeOpenDialogHook; 168end; 169 170//=== { TJclOpenDialogFavoritesHook } ======================================== 171 172constructor TJclOpenDialogFavoritesHook.Create; 173begin 174 inherited Create; 175 FFavoriteFolders := TStringList.Create; 176 177 {$IFDEF OLDSTYLE} 178 FFavoritePanel := TPanel.Create(nil); 179 FFavoritePanel.Name := 'FavoritePanel'; 180 FFavoritePanel.BevelOuter := bvNone; 181 FFavoritePanel.Caption := ''; 182 FFavoritePanel.FullRepaint := False; 183 184 FFavoriteComboBox := TComboBox.Create(nil); 185 FFavoriteComboBox.Parent := FFavoritePanel; 186 FFavoriteComboBox.Align := alClient; 187 FFavoriteComboBox.Style := csDropDownList; 188 FFavoriteComboBox.Sorted := True; 189 FFavoriteComboBox.OnClick := FavoriteComboBoxClick; 190 191 FFavoriteStaticText := TStaticText.Create(nil); 192 FFavoriteStaticText.SetBounds(6, 18, FFavoriteStaticText.Width, FFavoriteStaticText.Height); 193 FFavoriteStaticText.Caption := LoadResString(@RsOpenDialogFavorites); 194 FFavoriteStaticText.AutoSize := True; 195 FFavoriteStaticText.FocusControl := FFavoriteComboBox; 196 {$ENDIF OLDSTYLE} 197 198 FTextAdd := LoadResString(@RsOpenDialogAdd); 199 FTextDelete := LoadResString(@RsOpenDialogDelete); 200 FTextVirtual := LoadResString(@RsOpenDialogVirtual); 201 202 {$IFDEF NEWSTYLE} 203 FTextList := LoadResString(@RsOpenDialogList); 204 {$ENDIF NEWSTYLE} 205end; 206 207destructor TJclOpenDialogFavoritesHook.Destroy; 208begin 209 {$IFDEF OLDSTYLE} 210 FreeAndNil(FFavoriteComboBox); 211 FreeAndNil(FFavoritePanel); 212 FreeAndNil(FFavoriteStaticText); 213 {$ENDIF OLDSTYLE} 214 FreeAndNil(FFavoriteFolders); 215 inherited Destroy; 216end; 217 218{$IFDEF OLDSTYLE} 219procedure TJclOpenDialogFavoritesHook.DialogAdjustControlPos; 220var 221 FileTypeStaticTextRect, FileTypeEditRect, // ID = 1136 1089 222 FileNameStaticTextRect, FileNameEditRect: TRect; // ID = 1148 1090 223 224 procedure GetDlgItemRect(ItemID: Integer; var R: TRect); 225 begin 226 GetWindowRect(GetDlgItem(FParentWnd, ItemID), R); 227 MapWindowPoints(0, FParentWnd, R, 2); 228 end; 229 230begin 231 inherited DialogAdjustControlPos; 232 233 GetDlgItemRect(stc2, FileTypeStaticTextRect); 234 GetDlgItemRect(cmb1, FileTypeEditRect); 235 GetDlgItemRect(stc3, FileNameStaticTextRect); 236 GetDlgItemRect(cmb13, FileNameEditRect); 237 238 FFavoriteStaticText.Left := FileTypeStaticTextRect.Left; 239 FFavoriteStaticText.Top := 2 * FileTypeStaticTextRect.Top - FileNameStaticTextRect.Top; 240 241 FFavoritePanel.Left := FileNameEditRect.Left; 242 FFavoritePanel.Top := 2 * FileTypeEditRect.Top - FileNameEditRect.Top; 243 FFavoritePanel.Width := FileTypeEditRect.Right - FileTypeEditRect.Left; 244end; 245 246procedure TJclOpenDialogFavoritesHook.DialogClose; 247begin 248 inherited DialogClose; 249 if not IsOpenPictureDialog then 250 begin 251 FFavoriteComboBox.Items.Delete(0); 252 FavoriteFolders.Assign(FFavoriteComboBox.Items); 253 end; 254 FFavoritePanel.ParentWindow := 0; 255 FFavoriteStaticText.ParentWindow := 0; 256 FParentWnd := 0; 257end; 258 259procedure TJclOpenDialogFavoritesHook.DialogFolderChange; 260var 261 Path: string; 262begin 263 inherited DialogFolderChange; 264 Path := CurrentFolder; 265 FFavoriteComboBox.ItemIndex := FFavoriteComboBox.Items.IndexOf(Path); 266 if FFavoriteComboBox.ItemIndex = -1 then 267 begin 268 if Path <> '' then 269 FFavoriteComboBox.Items[0] := FTextAdd 270 else 271 FFavoriteComboBox.Items[0] := FTextVirtual; 272 FFavoriteComboBox.ItemIndex := 0; 273 end 274 else 275 FFavoriteComboBox.Items[0] := FTextDelete; 276 FFavoriteComboBox.Invalidate; 277end; 278 279procedure TJclOpenDialogFavoritesHook.DialogShow; 280begin 281 inherited DialogShow; 282 if not IsOpenPictureDialog then 283 begin 284 FFavoritePanel.ParentWindow := FHandle; 285 FFavoriteStaticText.ParentWindow := FHandle; 286 FFavoriteComboBox.Items.Assign(FavoriteFolders); 287 FFavoriteComboBox.Items.Insert(0, FTextAdd); 288 end; 289end; 290 291procedure TJclOpenDialogFavoritesHook.FavoriteComboBoxClick(Sender: TObject); 292var 293 I: Integer; 294 Path: string; 295begin 296 if FFavoriteComboBox.ItemIndex = 0 then 297 begin 298 Path := CurrentFolder; 299 I := FFavoriteComboBox.Items.IndexOf(Path); 300 if I > 0 then 301 begin 302 // delete current folder 303 if MessageBox(FHandle, 304 PChar(Format(LoadResString(@RsOpenDialogDelConfirm), [Path])), 305 PChar(LoadResString(@RsOpenDialogConfirmation)), 306 MB_YESNO or MB_ICONQUESTION or MB_DEFBUTTON2) = ID_YES then 307 begin 308 FFavoriteComboBox.Items.Delete(I); 309 FFavoriteComboBox.Items[0] := FTextAdd; 310 FFavoriteComboBox.ItemIndex := 0; 311 end; 312 end 313 else 314 if Path <> '' then 315 begin 316 // add current folder 317 FFavoriteComboBox.ItemIndex := FFavoriteComboBox.Items.Add(Path); 318 FFavoriteComboBox.Items[0] := FTextDelete; 319 end; 320 FFavoriteComboBox.Invalidate; 321 end 322 else 323 if FFavoriteComboBox.ItemIndex > 0 then 324 // switch to selected folder 325 CurrentFolder := FFavoriteComboBox.Items[FFavoriteComboBox.ItemIndex]; 326end; 327{$ENDIF OLDSTYLE} 328 329{$IFDEF NEWSTYLE} 330procedure TJclOpenDialogFavoritesHook.FileDialogCreate( 331 const AFileDialog: IFileDialog); 332var 333 FileDialogCustomize: IFileDialogCustomize; 334 Unused: Cardinal; 335begin 336 inherited FileDialogCreate(AFileDialog); 337 FileDialogCustomize := AFileDialog as IFileDialogCustomize; 338 //CheckOSError(FileDialogCustomize.StartVisualGroup(CTRLID_GROUP, PWideChar(WideString(LoadResString(@RsOpenDialogFavorites))))); 339 CheckOSError(FileDialogCustomize.AddComboBox(CTRLID_COMBOBOX)); 340 //CheckOSError(FileDialogCustomize.EndVisualGroup); 341 CheckOSError(FileDialogCustomize.MakeProminent(CTRLID_COMBOBOX)); 342 CheckOSError(AFileDialog.Advise(Self, Unused)); 343end; 344 345procedure TJclOpenDialogFavoritesHook.FileDialogCleanCombobox( 346 const AFileDialogCustomize: IFileDialogCustomize); 347var 348 I: Integer; 349begin 350 if FComboboxListItem then 351 CheckOSError(AFileDialogCustomize.RemoveControlItem(CTRLID_COMBOBOX, ITEMID_LIST)); 352 FComboboxListItem := False; 353 if FComboboxAddItem then 354 CheckOSError(AFileDialogCustomize.RemoveControlItem(CTRLID_COMBOBOX, ITEMID_ADD)); 355 FComboboxAddItem := False; 356 if FComboboxDeleteItem then 357 CheckOSError(AFileDialogCustomize.RemoveControlItem(CTRLID_COMBOBOX, ITEMID_DELETE)); 358 FComboboxDeleteItem := False; 359 if FComboboxVirtualItem then 360 CheckOSError(AFileDialogCustomize.RemoveControlItem(CTRLID_COMBOBOX, ITEMID_VIRTUAL)); 361 FComboboxVirtualItem := False; 362 for I := 0 to FComboboxCount - 1 do 363 CheckOSError(AFileDialogCustomize.RemoveControlItem(CTRLID_COMBOBOX, I)); 364 FComboboxCount := 0; 365end; 366 367procedure TJclOpenDialogFavoritesHook.FileDialogFillCombobox( 368 const AFileDialogCustomize: IFileDialogCustomize; ListItem, AddItem, DeleteItem, VirtualItem: Boolean); 369var 370 I: Integer; 371begin 372 if ListItem then 373 CheckOSError(AFileDialogCustomize.AddControlItem(CTRLID_COMBOBOX, ITEMID_LIST, PWideChar(WideString(FTextList)))); 374 FComboboxListItem := ListItem; 375 if AddItem then 376 CheckOSError(AFileDialogCustomize.AddControlItem(CTRLID_COMBOBOX, ITEMID_ADD, PWideChar(WideString(FTextAdd)))); 377 FComboboxAddItem := AddItem; 378 if DeleteItem then 379 CheckOSError(AFileDialogCustomize.AddControlItem(CTRLID_COMBOBOX, ITEMID_DELETE, PWideChar(WideString(FTextDelete)))); 380 FComboboxDeleteItem := DeleteItem; 381 if VirtualItem then 382 CheckOSError(AFileDialogCustomize.AddControlItem(CTRLID_COMBOBOX, ITEMID_VIRTUAL, PWideChar(WideString(FTextVirtual)))); 383 FComboboxVirtualItem := VirtualItem; 384 FComboboxCount := FFavoriteFolders.Count; 385 for I := 0 to FComboboxCount - 1 do 386 CheckOSError(AFileDialogCustomize.AddControlItem(CTRLID_COMBOBOX, I, PWideChar(WideString(FFavoriteFolders.Strings[I])))); 387end; 388{$ENDIF NEWSTYLE} 389 390procedure TJclOpenDialogFavoritesHook.LoadFavorites(const FileName: string); 391begin 392 if FileExists(FileName) then 393 FavoriteFolders.LoadFromFile(FileName) 394 else 395 FavoriteFolders.Clear; 396end; 397 398{$IFDEF NEWSTYLE} 399function TJclOpenDialogFavoritesHook.OnButtonClicked( 400 const pfdc: IFileDialogCustomize; dwIDCtl: DWORD): HResult; 401begin 402 Result := S_OK; 403end; 404 405function TJclOpenDialogFavoritesHook.OnCheckButtonToggled( 406 const pfdc: IFileDialogCustomize; dwIDCtl: DWORD; bChecked: BOOL): HResult; 407begin 408 Result := S_OK; 409end; 410 411function TJclOpenDialogFavoritesHook.OnControlActivating( 412 const pfdc: IFileDialogCustomize; dwIDCtl: DWORD): HResult; 413begin 414 Result := S_OK; 415end; 416 417function TJclOpenDialogFavoritesHook.OnFileOk(const pfd: IFileDialog): HResult; 418begin 419 Result := S_OK; 420end; 421 422function TJclOpenDialogFavoritesHook.OnFolderChange( 423 const pfd: IFileDialog): HResult; 424var 425 pfdc: IFileDialogCustomize; 426 ppsi: IShellItem; 427 Path: PWideChar; 428 ItemIndex: Integer; 429begin 430 Result := S_OK; 431 pfdc := pfd as IFileDialogCustomize; 432 CheckOSError(pfd.GetFolder(ppsi)); 433 if not Succeeded(ppsi.GetDisplayName(SIGDN_FILESYSPATH, Path)) then 434 Path := nil; 435 ItemIndex := FFavoriteFolders.IndexOf(Path); 436 if ItemIndex = -1 then 437 begin 438 if Path <> '' then 439 begin 440 FileDialogCleanCombobox(pfdc); 441 FileDialogFillCombobox(pfdc, True, True, False, False); 442 CheckOSError(pfdc.SetSelectedControlItem(CTRLID_COMBOBOX, ITEMID_LIST)); 443 end 444 else 445 begin 446 FileDialogCleanCombobox(pfdc); 447 FileDialogFillCombobox(pfdc, False, False, False, True); 448 CheckOSError(pfdc.SetSelectedControlItem(CTRLID_COMBOBOX, ITEMID_VIRTUAL)); 449 end; 450 end 451 else 452 begin 453 FileDialogCleanCombobox(pfdc); 454 FileDialogFillCombobox(pfdc, False, False, True, False); 455 CheckOSError(pfdc.SetSelectedControlItem(CTRLID_COMBOBOX, ItemIndex)); 456 end; 457end; 458 459function TJclOpenDialogFavoritesHook.OnFolderChanging(const pfd: IFileDialog; 460 const psiFolder: IShellItem): HResult; 461begin 462 Result := S_OK; 463end; 464 465function TJclOpenDialogFavoritesHook.OnItemSelected( 466 const pfdc: IFileDialogCustomize; dwIDCtl, dwIDItem: DWORD): HResult; 467var 468 I: Integer; 469 pfd: IFileDialog; 470 ppsi: IShellItem; 471 Path: PWideChar; 472begin 473 Result := S_OK; 474 if dwIDCtl = CTRLID_COMBOBOX then 475 begin 476 pfd := pfdc as IFileDialog; 477 CheckOSError(pfd.GetFolder(ppsi)); 478 if not Succeeded(ppsi.GetDisplayName(SIGDN_FILESYSPATH, Path)) then 479 Path := nil; 480 if dwIDItem = ITEMID_DELETE then 481 begin 482 I := FFavoriteFolders.IndexOf(Path); 483 if I >= 0 then 484 begin 485 // delete current folder 486 if MessageBox(0, 487 PChar(Format(LoadResString(@RsOpenDialogDelConfirm), [Path])), 488 PChar(LoadResString(@RsOpenDialogConfirmation)), 489 MB_YESNO or MB_ICONQUESTION or MB_DEFBUTTON2) = ID_YES then 490 begin 491 FFavoriteFolders.Delete(I); 492 FileDialogCleanCombobox(pfdc); 493 FileDialogFillCombobox(pfdc, True, True, False, False); 494 CheckOSError(pfdc.SetSelectedControlItem(CTRLID_COMBOBOX, ITEMID_LIST)); 495 end; 496 end; 497 end 498 else 499 if dwIDItem = ITEMID_ADD then 500 begin 501 if Path <> '' then 502 begin 503 // add current folder 504 I := FFavoriteFolders.Add(Path); 505 FileDialogCleanCombobox(pfdc); 506 FileDialogFillCombobox(pfdc, False, False, True, False); 507 CheckOSError(pfdc.SetSelectedControlItem(CTRLID_COMBOBOX, I)); 508 end; 509 end 510 else 511 //if dwIDItem >= 0 then 512 begin 513 // switch to selected folder 514 CheckOSError(SHCreateItemFromParsingName(PWideChar(WideString(FFavoriteFolders.Strings[dwIDItem])), nil, IShellItem, ppsi)); 515 CheckOSError(pfd.SetFolder(ppsi)); 516 FileDialogCleanCombobox(pfdc); 517 FileDialogFillCombobox(pfdc, False, False, True, False); 518 CheckOSError(pfdc.SetSelectedControlItem(CTRLID_COMBOBOX, dwIDItem)); 519 end; 520 end; 521end; 522 523function TJclOpenDialogFavoritesHook.OnOverwrite(const pfd: IFileDialog; 524 const psi: IShellItem; out pResponse: DWORD): HResult; 525begin 526 Result := S_OK; 527end; 528 529function TJclOpenDialogFavoritesHook.OnSelectionChange( 530 const pfd: IFileDialog): HResult; 531begin 532 Result := S_OK; 533end; 534 535function TJclOpenDialogFavoritesHook.OnShareViolation(const pfd: IFileDialog; 536 const psi: IShellItem; out pResponse: DWORD): HResult; 537begin 538 Result := S_OK; 539end; 540 541function TJclOpenDialogFavoritesHook.OnTypeChange( 542 const pfd: IFileDialog): HResult; 543begin 544 Result := S_OK; 545end; 546 547function TJclOpenDialogFavoritesHook.QueryInterface(const IID: TGUID; 548 out Obj): HResult; 549begin 550 if GetInterface(IID, Obj) then 551 Result := 0 552 else 553 Result := E_NOINTERFACE; 554end; 555 556function TJclOpenDialogFavoritesHook._AddRef: Integer; 557begin 558 Result := -1; 559end; 560 561function TJclOpenDialogFavoritesHook._Release: Integer; 562begin 563 Result := -1; 564end; 565{$ENDIF NEWSTYLE} 566 567{$IFDEF UNITVERSIONING} 568initialization 569 RegisterUnitVersion(HInstance, UnitVersioning); 570 571finalization 572 UnregisterUnitVersion(HInstance); 573{$ENDIF UNITVERSIONING} 574 575end.