Search code examples
delphiwinapidlldelphi-7hwnd

How to pass a form handle to a DLL for use in Windows API?


First of all, I'm not too comfortable with DLL's. I've done them before, but know very little and always have problems.

This DLL I'm building requires passing a windows form handle (HWND) into the DLL function, and the DLL shall call a Windows API function using that handle. I keep getting an access violation when trying to call any function (starting from Win7InitTaskbar) - as if it failed to even call the function. That made me conclude that it must be the HWND parameter making it crash... I think...

library Win7;

uses
  //Do I need ShareMem?
  //ShareMem,      //<---
  Windows,
  Forms,
  JDWin7,
  SysUtils,
  Classes;

{$R *.res}

function Win7InitTaskbar(const FormHandle: HWND): Bool; stdcall;
begin
  Result:= InitializeTaskbarAPI(FormHandle);
end;

function Win7InitForm(const FormHandle: HWND): Bool; stdcall;
begin

end;

function Win7SetTaskbarState(const AState: Cardinal): Bool; stdcall;
begin
  Result:= SetTaskbarProgressState(AState);
end;

function Win7SetTaskbarValue(const ACurrent: UInt64; const AMax: UInt64): Bool; stdcall;
begin                                        //is UInt64 Safe for DLL?
  Result:= SetTaskbarProgressValue(ACurrent, AMax);
end;

exports
  Win7InitTaskbar,
  Win7InitForm,
  Win7SetTaskbarState,
  Win7SetTaskbarValue;

begin
end.

Implementation of DLL functions:

function Win7InitTaskbar(const FormHandle: HWND): Bool;
  external W7DLL;
function Win7SetTaskbarState(const AState: Cardinal): Bool;
  external W7DLL;
function Win7SetTaskbarValue(const ACurrent: UInt64; const AMax: UInt64): Bool;
  external W7DLL;

I had this problem whether I used ShareMem or not (Which, I also do not want to use). Is it safe to publish the function with a HWND parameter? I tried LongWord as well, still no luck. The internal function InitializeTaskbarAPI does in fact work perfectly outside of the DLL, if i were to use it directly inside the app. But in this case, I want to put these in a shared DLL.

Also, is it safe to pass UInt64 into a DLL? One of the functions was already published with this parameter type when I got the source.


Solution

  • Your problem here appears to me to be unrelated to using Sharemem or passing Form.Handle to an HWND parameter.

    It is simply a calling convention mismatch. You export as stdcall but then import as register. Whenever you do that, runtime errors are sure to follow.

    You need to do it like this:

    function Win7InitTaskbar(const FormHandle: HWND): Bool; 
      stdcall; external W7DLL;
    function Win7SetTaskbarState(const AState: Cardinal): Bool;
      stdcall; external W7DLL;
    function Win7SetTaskbarValue(const ACurrent: UInt64; const AMax: UInt64): Bool;
      stdcall; external W7DLL;
    

    And for what it is worth, you don't need Sharemem here. You only need that when you allocate memory in one module but free it in a different one. And passing Form.Handle to an HWND parameter in a DLL is not a problem. You do this all then time when you call Windows API functions.