Delphi 7 component changes, fixes and important notes
-----------------------------------------------------

- if I ever upgrade to Delphi XE 10 Seattle, make sure to change all WideChar() vars/calls to Char() type as
  the "String" var type is now Unicode string type; also, change all "WideString" vars to "String"... same reason

- Graphics.pas must be declared AFTER ZipForge.pas in the "uses" section... for font color definitions

- uCommon.PosEx() function doesn't work with WideString, only String!
  must use uCommon.Pos() function for Unicode (Delphi WideString)

- no need to stop thread timer when closing FormStatus (it stops automatically)

- function uMain.LoadFolderSpecial_MAME() is used to load paths for Artwork, Input, Samples (March 17, 2016)
  ... is this function deprecated ???? (August 31, 2016)

- longest game name is 16 chars (hard-coded in MAME's source... for now). Device set "Keytronic PC3270" (keytronic_pc3270)

- ImgList.pas must be defined AFTER the BarMenu(s).pas files (uses section)

- SHA-1 checksum support was added in v0.68 (v0.67 and older only have CRC32 checksum)

- SHA-1 for CHD files started at MAME v0.78 (-listxml)
  -> for old MAME builds (v0.67 and older, there is no SHA-1 for ROMs, only CRC)

- MPCommonUtilities.pas "FillGradient()" function have an interesting function "StartPoint" / "EndPoint" to draw only partial areas or the gradient

.................... IMPORTANT!!!!!........................ 

Here is how to increase the pixels in EasyListView "ShowThemeBorder" (is 1 pixel)
https://www.programering.com/q/MzNyUTMwATc.html

-> MPCommonObjects.pas

procedure TCommonCanvasControl.WMNCCalcSize(var Msg: TWMNCCalcSize);
begin
  // increase the border to 20 pixels
  Inc(lpncsp^.rgrc[0].Left   , 20);
  Inc(lpncsp^.rgrc[0].Top    , 20);

  Dec(lpncsp^.rgrc[0].Right  , 20);
  Dec(lpncsp^.rgrc[0].Bottom , 20);
end;

...........................................................


.................... IMPORTANT!!!!!........................ 

- check uMain.ValidateMultiSlot() and apply this optimization to all ELV.Selection.First() / Next() calls
  -> create a selection count and a selection index var to avoid ELV from going thru all items after the selection count is reached by the selection index var...
     ... all done, I think.
  
  ValidateMultiSlot() is a lot faster now.
  This is for all view modes

- games popup menu "Scan games with missing ROMs/CHDs" is using tag #4 but it should be using tag #7 (select system)
   -> the CallScanGames is using tag #4, but it seems to be working correctly.
   -> already fixed; tag #4 is kept but in the ScanGames() function it correctly uses the tag #7 (still, this might need changing!)

...........................................................

- var iUpdatedGames (uMain.pas) is used to count changed games and show game names+system after games scan... for debugging only

- variable "NumGamesChanged" in "uMain.CallScanGames()" function is used to reset the filters
  ...could it be used to display how many games have changed ? maybe

- Graphics32 component GR32.pas fixed by me to open image files without crashing; new flag "or fmShareDenyNone" in the
  following function... procedure TCustomBitmap32.LoadFromFile(const FileName: string);

- Delphi 7 components fixed by me due to Delphi limitations or bugs under Windows 7/ Windows 8:
    (modified Delphi 7 source files are included with EL's source code)
    - update Jan 21, 2014: there are other changes but I can't remember...
    - TProgressBar: flickering under Windows Vista / Windows 7 / Windows 8
    - TComboBoxEx: Item height list was limited to 16 pixels (it should be the same height as the
                   assigned ImageList)
    - TImagelist: - icon size limitation removed
                  - native 32-bit support (alpha blend)
    - TTrackBar: - ticks flickering or something like that (can't remember)
                 - OnChange() event firing up 3 times in a row
    - TShellTreeView: there is a missing "override" and a wrong ClearItems in TCustomShellTreeView.Destroy

- procedure uMain.PopulateMachineToUsePopupMenu(const SoftwareName: String);
  it load supported machines into a popup menu... not used anymore (July 23, 2015)

- delete uMain.LoadSoftwareListXML; function ??????????? it parses "softlist.xml" files directly into the games list 
  without creating games list but it's too slow...

- var "IsWin7" (uMain.pas) is no longer used for anything; not needed

- loading MAME save state files... there cannot be the .sta extesion at the end of MAME will fail to load the file!!!

- loading MAME input files... the .inp extension MUST exist or MAME will fail to load the file!!!


{ TCustomShellTreeView }
...
TCustomShellTreeView = class(TCustomTreeView, IShellCommandVerb)
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override; //$$jp shellctrl.pas 26.08.2007: missing "override"
procedure Refresh(Node: TTreeNode);
...

destructor TCustomShellTreeView.Destroy;
begin
//$$jp: ClearItems;
//$$jp: raises EInvalidOperation and access-violations (shellctrl.pas 26.08.2007)
FRootFolder.Free;
inherited;
end;

- function uMain.ELV_PopulateSystems() adds "all systems" (create games list, scan games) and no item is hidden (only "ghosted")
  and MAWS/Progetto EMMA is only added in "categories settings" to hide it from categories popup menus... (when ELV has checkbboxes)

- ALL projects must have this to override Delphi's ugly hand cursor with the nice Windows hand cursor
  Screen.Cursors[crHandPoint]:= LoadCursor(0, IDC_HAND);

- remember to set Ctl3D property to TRUE on all TAdvGroupBox components (Ctl3D is off by default)

- remember, AdvGroupBox's CheckBox "click" event is set to "OnCheckBoxClick", not "OnClick" event

- 2013: new Delphi 7 change: IniFiles.pas "function TStringHash.HashOf(const Key: string): Cardinal;" it's in
  asm optimized language now. not sure if it makes this feature faster, but it works without any bugs

- November 2013: added a "Ghosted" property in TEasyItem (public section) to check for ghosted items easily (EasyListview.pas)

- changes in EasyListView.pas (July 26, 2015): implemented multi-line captions for report view (small icon view)

  -> procedure TEasyViewSmallIconItem.ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString;
                                                    var RectArray: TEasyRectArrayObject);

  -> function TEasyViewSmallIconItem.PaintTextLineCount(Item: TEasyItem; Column: TEasyColumn): Integer;


- fixes for EasyListView.pas 

  -> fix the StateImageIndex = -1 and avoid it painting a space instead of moving the text back...
  file: "EasyListView.pas"
  procedure TEasyViewSmallIconItem.ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas;
                                            const Caption: WideString; var RectArray: TEasyRectArrayObject);

  -> replace this line:
     if PaintStateImage and  ((StateImageIndex > -1) or (GetImageList(Column, Item, eikState) <> nil)) then

  -> by this one:
     if PaintStateImage and  ((StateImageIndex > -1) and (GetImageList(Column, Item, eikState) <> nil)) then

- another fix for EasyListView... no alpha blend, with gradient and rounded corners (factor 2 max)
  add the following into
  
  "procedure TEasyViewItem.PaintSelectionRect()
   begin
     if OwnerListview.Selection.Gradient and not OwnerListview.Selection.AlphaBlend then
        begin
          if OwnerListview.Selection.RoundRect then
             begin
               FillGradient(LocalSelWindowClippedRect.Left, LocalSelWindowClippedRect.Top, LocalSelWindowClippedRect.Right,
               LocalSelWindowClippedRect.Bottom {- 1}, GradientTop, GradientBottom,
               LocalSelWindowClippedRect.Top+1, LocalSelWindowClippedRect.Bottom-2, ACanvas);
               ACanvas.Pen.Color:= ACanvas.Brush.Color;
               ACanvas.Brush.Style:= bsClear;
               ACanvas.RoundRect(LocalSelRect.Left, LocalSelRect.Top, LocalSelRect.Right, LocalSelRect.Bottom,
                                 OwnerListview.Selection.RoundRectRadius, OwnerListview.Selection.RoundRectRadius);
             end
          else
             begin
               FillGradient(LocalSelWindowClippedRect.Left, LocalSelWindowClippedRect.Top, LocalSelWindowClippedRect.Right,
               LocalSelWindowClippedRect.Bottom {- 1}, GradientTop, GradientBottom,
               LocalSelWindowClippedRect.Top+1, LocalSelWindowClippedRect.Bottom-2, ACanvas);
               ACanvas.FrameRect(LocalSelRect);
             end;
        end;
   end;

- cosmetic fix for EasyListview... focus rect is now a solid frame see Listview.pas
  procedure TEasyViewItem.PaintFocusRect(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ACanvas: TCanvas);

- EasyListView.pas ................................................
  TEasyViewItem.PaintAlphaBlendedRoundRect(ACanvas: TCanvas;
                 AlphaColor: TColor; GradientBottom: TColor; GradientTop: TColor;
                 var LocalSelWindowClippedRect: TRect; var Rgn: HRGN);

- TEasyViewItem.PaintSelectionRect() where it draws the non-alphablend gradient!!!!!!
  ... ACanvas.FrameRect(LocalSelRect);

- March 23, 2015 (EasyListView.pas): implemented "HideCaption" property to Tiles view mode, so check box can appear left side, vertically centered!!!!

  procedure TEasyViewTileItem.ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString;
                                            var RectArray: TEasyRectArrayObject);


- Delphi 2010 new routines!! "source\Win32\rtl\common\IOUtils.pas"...
  http://stackoverflow.com/questions/1642220/getting-size-of-a-file-in-d2010
  Maybe certain routines could be updated for Delphi 7... must check files

- function to scroll text to the top (RichEdit)

procedure ScrollMemoDown(Memo: TMemo);
begin
  SendMessage(Memo.Handle,{ HWND of the Memo Control }
    WM_VSCROLL,    { Windows Message }
    SB_PAGEDOWN,   { Scroll Command }
    0)             { Not Used }
end;


procedure ScrollMemoUp(Memo: TMemo);
begin      
  SendMessage(Memo.Handle, { HWND of the Memo Control }
    WM_VSCROLL,    { Windows Message }
    SB_PAGEUP,     { Scroll Command }
    0);            { Not Used }
end;


// Example, Beispiel:

procedure TForm1.Button1Click(Sender: TObject);
begin  
  ScrollMemoDown(Memo1);
end;

- Change height of items with 32 and 16 icon size BcDrawModule "onMeasureMenuItem" event
  Jan 21, 2014: some items are already treated there!

- check procedure TEasyViewItem.PaintAlphaBlendedRoundRect() to learn how to do alpha blend and
   a round rect region with alpha blending.... ^-^

- [MAYBE ??] try to change EasyListView to make dual gradient selection bar
              .... on EasyListView / MPCommonUtilities.FillGradient

- [MAYBE!!!] updates for Delphi XE7 2015 (not all are necessary)
  -> Create the project and all screens from scratch to avoid old properties/events from Delphi 7
     ... but copy and paste all custom functions, procedures and components events (.pas) 
  -> [MAYBE] remove GraphicEx library from project since D2012 have PNG/GIF/JPG .dcu libraries
  -> [MAYBE] change edit boxes that have a button (browse, select...) by the new buttoned edit box component
  -> [MAYBE] remove "madCollections" (madExcept). this library only facilitates to find where the crash happens.
     Delphi 2012 an newer seems to have a more detailed debugger (not sure though)
  -> is FastMM still necessary ? I think so... need to check the one bundled with XE7
  -> ask ZipForge author to give me a nag-free build compatible with Delphi xE7... without that annoying nag screen
     (no source code required!)...
  -> [MAYBE ?] support aero glass interface

- convert to UTF-8 from WideString (src\osd\sdl\sdlmain.c)

//============================================================
//  wstring_from_utf8
//============================================================

WCHAR *wstring_from_utf8(const char *utf8string)
{
	int char_count;
	WCHAR *result;

	// convert MAME string (UTF-8) to UTF-16
	char_count = MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, NULL, 0);
	result = (WCHAR *)osd_malloc_array(char_count * sizeof(*result));
	if (result != NULL)
		MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, result, char_count);

	return result;
}

//============================================================
//  utf8_from_wstring
//============================================================

char *utf8_from_wstring(const WCHAR *wstring)
{
	int char_count;
	char *result;

	// convert UTF-16 to MAME string (UTF-8)
	char_count = WideCharToMultiByte(CP_UTF8, 0, wstring, -1, NULL, 0, NULL, NULL);
	result = (char *)osd_malloc_array(char_count * sizeof(*result));
	if (result != NULL)
		WideCharToMultiByte(CP_UTF8, 0, wstring, -1, result, char_count, NULL, NULL);

	return result;
}

- MAME BGFX backend
  "gles" -> valid : OpenGL ES
  "glsl" -> invalid: it's just OpenGL (valid: "opengl")
  "metal" -> invalid for Windows... I think this is for MAC OS only ?????

- function uMain.LoadFolders_ConfigFiles() does it need a emu exe filename parameter ??????????
  March 24, 2016: no, it doesn't because this function is only used when deleting files of selected game(s) and
  when deleting files of multiple games  
