summaryrefslogtreecommitdiff
path: root/plugins/Utils.pas/wrapper.pas
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Utils.pas/wrapper.pas')
-rw-r--r--plugins/Utils.pas/wrapper.pas513
1 files changed, 513 insertions, 0 deletions
diff --git a/plugins/Utils.pas/wrapper.pas b/plugins/Utils.pas/wrapper.pas
new file mode 100644
index 0000000000..91f7b23b0b
--- /dev/null
+++ b/plugins/Utils.pas/wrapper.pas
@@ -0,0 +1,513 @@
+{$include compilers.inc}
+unit wrapper;
+
+interface
+
+uses windows;
+
+function CreateHiddenWindow(proc:pointer=nil):HWND;
+
+function DoInitCommonControls(dwICC:DWORD):boolean;
+
+function GetScreenRect:TRect;
+procedure SnapToScreen(var rc:TRect;dx:integer=0;dy:integer=0{;
+ minw:integer=240;minh:integer=100});
+
+function GetDlgText(Dialog:HWND;idc:integer;getAnsi:boolean=false):pointer; overload;
+function GetDlgText(wnd:HWND;getAnsi:boolean=false):pointer; overload;
+
+function StringToGUID(const astr:PAnsiChar):TGUID; overload;
+function StringToGUID(const astr:PWideChar):TGUID; overload;
+
+// Comboboxes
+function CB_SelectData(cb:HWND;data:dword):lresult; overload;
+function CB_SelectData(Dialog:HWND;id:cardinal;data:dword):lresult; overload;
+function CB_GetData (cb:HWND;idx:integer=-1):lresult;
+function CB_AddStrData (cb:HWND;astr:pAnsiChar;data:integer=0;idx:integer=-1):HWND;
+function CB_AddStrDataW(cb:HWND;astr:pWideChar;data:integer=0;idx:integer=-1):HWND;
+
+// CommCtrl - ListView
+Procedure ListView_GetItemTextA(hwndLV:hwnd;i:WPARAM;iSubItem:integer;pszText:Pointer;cchTextMax:integer);
+Procedure ListView_GetItemTextW(hwndLV:hwnd;i:WPARAM;iSubItem:integer;pszText:Pointer;cchTextMax:integer);
+function LV_GetLParam (list:HWND;item:integer=-1):lresult;
+function LV_SetLParam (list:HWND;lParam:LPARAM;item:integer=-1):lresult;
+function LV_ItemAtPos(wnd:HWND;pt:TPOINT;var SubItem:dword):Integer; overload;
+function LV_ItemAtPos(wnd:HWND;x,y:integer;var SubItem:dword):Integer; overload;
+procedure LV_SetItem (handle:hwnd;str:PAnsiChar;item:integer;subitem:integer=0);
+procedure LV_SetItemW(handle:hwnd;str:PWideChar;item:integer;subitem:integer=0);
+function LV_MoveItem(list:hwnd;direction:integer;item:integer=-1):integer;
+function LV_GetColumnCount(list:HWND):lresult;
+function LV_CheckDirection(list:HWND):integer; // bit 0 - can move up, bit 1 - down
+
+// CommDLG - Dialogs
+function ShowDlg (dst:PAnsiChar;fname:PAnsiChar=nil;Filter:PAnsiChar=nil;open:boolean=true):boolean;
+function ShowDlgW(dst:PWideChar;fname:PWideChar=nil;Filter:PWideChar=nil;open:boolean=true):boolean;
+
+implementation
+
+uses messages,common,commctrl,commdlg;
+
+const
+ EmptyGUID:TGUID = '{00000000-0000-0000-0000-000000000000}';
+
+{$IFNDEF FPC}
+const
+ LVM_SORTITEMSEX = LVM_FIRST + 81;
+{$ENDIF}
+
+{$IFNDEF DELPHI_7_UP}
+const
+ SM_XVIRTUALSCREEN = 76;
+ SM_YVIRTUALSCREEN = 77;
+ SM_CXVIRTUALSCREEN = 78;
+ SM_CYVIRTUALSCREEN = 79;
+{$ENDIF}
+
+//----- Hidden Window functions -----
+const
+ HWND_MESSAGE = HWND(-3);
+const
+ hiddenwindow:HWND = 0;
+ hwndcount:integer=0;
+
+function HiddenWindProc(wnd:HWnd; msg:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+begin
+ if msg=WM_CLOSE then
+ begin
+ dec(hwndcount);
+ if hwndcount>0 then // not all references gone
+ begin
+ result:=0;
+ exit
+ end
+ else
+ hiddenwindow:=0
+ end;
+
+ result:=DefWindowProcW(wnd,msg,wParam,lParam);
+end;
+
+function CreateHiddenWindow(proc:pointer=nil):HWND;
+begin
+ if proc=nil then
+ begin
+ if hiddenwindow<>0 then
+ begin
+ result:=hiddenwindow;
+ inc(hwndcount); // one reference more
+ end
+ else
+ begin
+ result:=CreateWindowExW(0,'STATIC',nil,0,
+ 1,1,1,1,HWND_MESSAGE,0,hInstance,nil);
+ if result<>0 then
+ SetWindowLongPtrW(result,GWL_WNDPROC,LONG_PTR(@HiddenWindProc));
+
+ hiddenwindow:=result;
+ end
+ end
+ else
+ begin
+ result:=CreateWindowExW(0,'STATIC',nil,0,
+ 1,1,1,1,HWND_MESSAGE,0,hInstance,nil);
+ if result<>0 then
+ SetWindowLongPtrW(result,GWL_WNDPROC,LONG_PTR(proc));
+ end;
+end;
+//----- End of hidden window functions -----
+
+function DoInitCommonControls(dwICC:DWORD):boolean;
+var
+ ICC: TInitCommonControlsEx;
+begin
+ if dwICC=0 then
+ dwICC:=ICC_STANDARD_CLASSES or ICC_WIN95_CLASSES;
+ ICC.dwSize:= Sizeof(ICC);
+ ICC.dwICC := dwICC;
+ result:=InitCommonControlsEx(ICC);
+end;
+
+function GetScreenRect:TRect;
+begin
+ result.left := GetSystemMetrics( SM_XVIRTUALSCREEN );
+ result.top := GetSystemMetrics( SM_YVIRTUALSCREEN );
+ result.right := GetSystemMetrics( SM_CXVIRTUALSCREEN ) + result.left;
+ result.bottom:= GetSystemMetrics( SM_CYVIRTUALSCREEN ) + result.top;
+end;
+
+procedure SnapToScreen(var rc:TRect;dx:integer=0;dy:integer=0{;
+ minw:integer=240;minh:integer=100});
+var
+ rect:TRect;
+begin
+ rect:=GetScreenRect;
+ if rc.right >rect.right then rc.right :=rect.right -dx;
+ if rc.bottom>rect.bottom then rc.bottom:=rect.bottom-dy;
+ if rc.left <rect.left then rc.left :=rect.left;
+ if rc.top <rect.top then rc.top :=rect.top;
+end;
+
+function GetDlgText(wnd:HWND;getAnsi:boolean=false):pointer;
+var
+ a:cardinal;
+begin
+ result:=nil;
+ if getAnsi then
+ begin
+ a:=SendMessageA(wnd,WM_GETTEXTLENGTH,0,0)+1;
+ if a>1 then
+ begin
+ mGetMem(PAnsiChar(result),a);
+ SendMessageA(wnd,WM_GETTEXT,a,lparam(result));
+ end;
+ end
+ else
+ begin
+ a:=SendMessageW(wnd,WM_GETTEXTLENGTH,0,0)+1;
+ if a>1 then
+ begin
+ mGetMem(pWideChar(result),a*SizeOf(WideChar));
+ SendMessageW(wnd,WM_GETTEXT,a,lparam(result));
+ end;
+ end;
+end;
+
+function GetDlgText(Dialog:HWND;idc:integer;getAnsi:boolean=false):pointer;
+begin
+ result:=GetDlgText(GetDlgItem(Dialog,idc),getAnsi);
+end;
+
+//----- Combobox functions -----
+
+function CB_SelectData(cb:HWND;data:dword):lresult; overload;
+var
+ i:integer;
+begin
+ result:=0;
+ for i:=0 to SendMessage(cb,CB_GETCOUNT,0,0)-1 do
+ begin
+ if data=dword(SendMessage(cb,CB_GETITEMDATA,i,0)) then
+ begin
+ result:=i;
+ break;
+ end;
+ end;
+ result:=SendMessage(cb,CB_SETCURSEL,result,0);
+end;
+
+function CB_SelectData(Dialog:HWND;id:cardinal;data:dword):lresult; overload;
+begin
+ result:=CB_SelectData(GetDlgItem(Dialog,id),data);
+end;
+
+function CB_GetData(cb:HWND;idx:integer=-1):lresult;
+begin
+ if idx<0 then
+ idx:=SendMessage(cb,CB_GETCURSEL,0,0);
+ if idx<0 then
+ result:=0
+ else
+ result:=SendMessage(cb,CB_GETITEMDATA,idx,0);
+end;
+
+function CB_AddStrData(cb:HWND;astr:pAnsiChar;data:integer=0;idx:integer=-1):HWND;
+begin
+ result:=cb;
+ if idx<0 then
+ idx:=SendMessageA(cb,CB_ADDSTRING,0,lparam(astr))
+ else
+ idx:=SendMessageA(cb,CB_INSERTSTRING,idx,lparam(astr));
+ SendMessageA(cb,CB_SETITEMDATA,idx,data);
+end;
+
+function CB_AddStrDataW(cb:HWND;astr:pWideChar;data:integer=0;idx:integer=-1):HWND;
+begin
+ result:=cb;
+ if idx<0 then
+ idx:=SendMessageW(cb,CB_ADDSTRING,0,lparam(astr))
+ else
+ idx:=SendMessageW(cb,CB_INSERTSTRING,idx,lparam(astr));
+ SendMessage(cb,CB_SETITEMDATA,idx,data);
+end;
+
+function StringToGUID(const astr:PAnsiChar):TGUID;
+var
+ i:integer;
+begin
+ result:=EmptyGUID;
+ if StrLen(astr)<>38 then exit;
+ result.D1:=HexToInt(PAnsiChar(@astr[01]),8);
+ result.D2:=HexToInt(PAnsiChar(@astr[10]),4);
+ result.D3:=HexToInt(PAnsiChar(@astr[15]),4);
+
+ result.D4[0]:=HexToInt(PAnsiChar(@astr[20]),2);
+ result.D4[1]:=HexToInt(PAnsiChar(@astr[22]),2);
+ for i:=2 to 7 do
+ begin
+ result.D4[i]:=HexToInt(PAnsiChar(@astr[21+i*2]),2);
+ end;
+end;
+
+function StringToGUID(const astr:PWideChar):TGUID;
+var
+ i:integer;
+begin
+ result:=EmptyGUID;
+ if StrLenW(astr)<>38 then exit;
+ result.D1:=HexToInt(pWideChar(@astr[01]),8);
+ result.D2:=HexToInt(pWideChar(@astr[10]),4);
+ result.D3:=HexToInt(pWideChar(@astr[15]),4);
+
+ result.D4[0]:=HexToInt(pWideChar(@astr[20]),2);
+ result.D4[1]:=HexToInt(pWideChar(@astr[22]),2);
+ for i:=2 to 7 do
+ begin
+ result.D4[i]:=HexToInt(pWideChar(@astr[21+i*2]),2);
+ end;
+end;
+
+//----- ListView functions -----
+
+Procedure ListView_GetItemTextA(hwndLV:hwnd;i:WPARAM;iSubItem:integer;pszText:Pointer;cchTextMax:integer);
+Var
+ lvi:LV_ITEMA;
+Begin
+ lvi.iSubItem :=iSubItem;
+ lvi.cchTextMax:=cchTextMax;
+ lvi.pszText :=pszText;
+ SendMessageA(hwndLV,LVM_GETITEMTEXT,i,LPARAM(@lvi));
+end;
+
+Procedure ListView_GetItemTextW(hwndLV:hwnd;i:WPARAM;iSubItem:integer;pszText:Pointer;cchTextMax:integer);
+Var
+ lvi:LV_ITEMW;
+Begin
+ lvi.iSubItem :=iSubItem;
+ lvi.cchTextMax:=cchTextMax;
+ lvi.pszText :=pszText;
+ SendMessageW(hwndLV,LVM_GETITEMTEXT,i,LPARAM(@lvi));
+end;
+
+procedure LV_SetItem(handle:hwnd;str:PAnsiChar;item:integer;subitem:integer=0);
+var
+ li:LV_ITEMA;
+begin
+// zeromemory(@li,sizeof(li));
+ li.mask :=LVIF_TEXT;
+ li.pszText :=str;
+ li.iItem :=item;
+ li.iSubItem:=subitem;
+ SendMessageA(handle,LVM_SETITEMA,0,lparam(@li));
+end;
+
+procedure LV_SetItemW(handle:hwnd;str:PWideChar;item:integer;subitem:integer=0);
+var
+ li:LV_ITEMW;
+begin
+// zeromemory(@li,sizeof(li));
+ li.mask :=LVIF_TEXT;
+ li.pszText :=str;
+ li.iItem :=item;
+ li.iSubItem:=subitem;
+ SendMessageW(handle,LVM_SETITEMW,0,lparam(@li));
+end;
+
+function LV_GetLParam(list:HWND;item:integer=-1):lresult;
+var
+ li:LV_ITEMW;
+begin
+ if item<0 then
+ begin
+ item:=SendMessage(list,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ if item<0 then
+ begin
+ result:=-1;
+ exit;
+ end;
+ end;
+ li.iItem :=item;
+ li.mask :=LVIF_PARAM;
+ li.iSubItem:=0;
+ SendMessageW(list,LVM_GETITEMW,0,lparam(@li));
+ result:=li.lParam;
+end;
+
+function LV_SetLParam(list:HWND;lParam:LPARAM;item:integer=-1):lresult;
+var
+ li:LV_ITEMW;
+begin
+ if item<0 then
+ begin
+ item:=SendMessage(list,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ if item<0 then
+ begin
+ result:=-1;
+ exit;
+ end;
+ end;
+ li.iItem :=item;
+ li.mask :=LVIF_PARAM;
+ li.lParam :=lParam;
+ li.iSubItem:=0;
+ SendMessageW(list,LVM_SETITEMW,0,windows.lparam(@li));
+ result:=lParam;
+end;
+
+function LV_ItemAtPos(wnd:HWND;Pt:TPOINT;var SubItem:dword):Integer;
+var
+ HTI:LV_HITTESTINFO;
+begin
+ HTI.pt.x := pt.X;
+ HTI.pt.y := pt.Y;
+ SendMessage(wnd,LVM_SUBITEMHITTEST,0,lparam(@HTI));
+ Result :=HTI.iItem;
+ if @SubItem<>nil then
+ SubItem:=HTI.iSubItem;
+end;
+
+function LV_ItemAtPos(wnd:HWND;x,y:integer;var SubItem:dword):Integer; overload;
+var
+ HTI:LV_HITTESTINFO;
+begin
+ HTI.pt.x := x;
+ HTI.pt.y := y;
+ SendMessage(wnd,LVM_SUBITEMHITTEST,0,lparam(@HTI));
+ Result :=HTI.iItem;
+ if @SubItem<>nil then
+ SubItem:=HTI.iSubItem;
+end;
+
+function LV_Compare(lParam1,lParam2,param:LPARAM):integer; stdcall;
+var
+ olditem,neibor:integer;
+begin
+ result:=lParam1-lParam2;
+ neibor :=hiword(param);
+ olditem:=loword(param);
+ if neibor>olditem then
+ begin
+ if (lParam1=olditem) and (lParam2<=neibor) then
+ result:=1;
+ end
+ else
+ begin
+ if (lParam2=olditem) and (lParam1>=neibor) then
+ result:=1;
+ end;
+end;
+
+function LV_MoveItem(list:hwnd;direction:integer;item:integer=-1):integer;
+begin
+ if ((direction>0) and (item=(SendMessage(list,LVM_GETITEMCOUNT,0,0)-1))) or
+ ((direction<0) and (item=0)) then
+ begin
+ result:=item;
+ exit;
+ end;
+
+ if item<0 then
+ item:=SendMessage(list,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+ SendMessageW(list,LVM_SORTITEMSEX,wparam(item)+(wparam(item+direction) shl 16),lparam(@LV_Compare));
+ result:=item+direction;
+end;
+
+function LV_GetColumnCount(list:HWND):lresult;
+begin
+ result:=SendMessage(SendMessage(list,LVM_GETHEADER,0,0),HDM_GETITEMCOUNT,0,0);
+end;
+
+function LV_CheckDirection(list:HWND):integer;
+var
+ i,cnt{,selcnt}:integer;
+ stat,first,last,focus: integer;
+begin
+ first :=-1;
+ last :=-1;
+ focus :=-1;
+ cnt :=SendMessage(list,LVM_GETITEMCOUNT,0,0)-1;
+// selcnt:=SendMessage(list,LVM_GETSELECTEDCOUNT,0,0);
+ for i:=0 to cnt do
+ begin
+ stat:=SendMessage(list,LVM_GETITEMSTATE,i,LVIS_SELECTED or LVIS_FOCUSED);
+ if (stat and LVIS_SELECTED)<>0 then
+ begin
+ if (stat and LVIS_FOCUSED)<>0 then
+ focus:=i;
+ if first<0 then first:=i;
+ last:=i;
+ end;
+ end;
+ result:=0;
+ if focus<0 then
+ focus:=first;
+ if focus>=0 then
+ result:=result or ((focus+1) shl 16);
+ if first>0 then // at least one selected and not first
+ begin
+ result:=(result or 1){ or (first+1) shl 16};
+ end;
+ if (last>=0) and (last<cnt) then
+ result:=result or 2;
+end;
+
+//----- CommDlg procedures -----
+
+function ShowDlg(dst:PAnsiChar;fname:PAnsiChar=nil;Filter:PAnsiChar=nil;open:boolean=true):boolean;
+var
+ NameRec:OpenFileNameA;
+begin
+ FillChar(NameRec,SizeOf(NameRec),0);
+ with NameRec do
+ begin
+ LStructSize:=SizeOf(NameRec);
+ if fname=nil then
+ dst[0]:=#0
+ else if fname<>dst then
+ StrCopy(dst,fname);
+// lpstrInitialDir:=dst;
+ if Filter<>nil then
+ begin
+ lpstrDefExt:=StrEnd(Filter)+1;
+ inc(lpstrDefExt,2); // skip "*."
+ end;
+ lpStrFile :=dst;
+ lpStrFilter:=Filter;
+ NMaxFile :=511;
+ Flags :=OFN_EXPLORER or OFN_OVERWRITEPROMPT;// or OFN_HIDEREADONLY;
+ end;
+ if open then
+ result:=GetOpenFileNameA({$IFDEF FPC}@{$ENDIF}NameRec)
+ else
+ result:=GetSaveFileNameA({$IFDEF FPC}@{$ENDIF}NameRec);
+end;
+
+function ShowDlgW(dst:PWideChar;fname:PWideChar=nil;Filter:PWideChar=nil;open:boolean=true):boolean;
+var
+ NameRec:OpenFileNameW;
+begin
+ FillChar(NameRec,SizeOf(NameRec),0);
+ with NameRec do
+ begin
+ LStructSize:=SizeOf(NameRec);
+ if fname=nil then
+ dst[0]:=#0
+ else if fname<>dst then
+ StrCopyW(dst,fname);
+// lpstrInitialDir:=dst;
+ if Filter<>nil then
+ begin
+ lpstrDefExt:=StrEndW(Filter)+1;
+ inc(lpstrDefExt,2); // skip "*."
+ end;
+ lpStrFile :=dst;
+ lpStrFilter:=Filter;
+ NMaxFile :=511;
+ Flags :=OFN_EXPLORER or OFN_OVERWRITEPROMPT;// or OFN_HIDEREADONLY;
+ end;
+ if open then
+ result:=GetOpenFileNameW({$IFDEF FPC}@{$ENDIF}NameRec)
+ else
+ result:=GetSaveFileNameW({$IFDEF FPC}@{$ENDIF}NameRec)
+end;
+
+end.