How I can determine when a window handle is valid? - delphi

I am writing a DLL which make some operations on a particular window, but sometimes the handle passed is not valid. Does there exist any function to validate that the handle passed is valid (belongs to a window)?

Try using the IsWindow function, which is declared in the Windows unit.
function IsWindow(hWnd: HWND): BOOL; stdcall;

Related

Is passing a DLL function argument with "const" an equivalent to pointer?

Data block:
PMyDataBlock = ^MyDataBlock;
MyDataBlock = record
// .............
end;
Is a following definition:
function MyFunction(const pstSettings: MyDataBlock): HRESULT; stdcall; external 'MyLib.dll' name 'MyFunction';
a full equivalent of this?:
function MyFunction(pstSettings: PMyDataBlock): HRESULT; stdcall; external 'MyLib.dll' name 'MyFunction';
The short answer is "No, it is not"
In your case, your record may or may not be passed by reference. The size of the record is 1 of the factor I know of that affect that behavior. If your record is 4 bytes or less, I believe it will be passed by value, otherwise, it will be passed by reference. I don't believe this behavior is contractual (In other word, Embarcadero is free to change it at any time in the future). In other words, it's a bad idea to use const parameter to call an external function.
If you want to pass your record by reference, the proper way to do would be to declare it var
function MyFunction(var pstSettings: MyDataBlock): HRESULT; stdcall; external 'MyLib.dll' name 'MyFunction';
or pass it as a pointer.

Delphi correct signature for LowLevelKeyboardProc()

I´m writing a global keyboard hook in Delphi 2007 and Windows 10. I´ve found different signatures for a Delphi LowLevelKeyboardProc callback. Someones like this and windows documentation (https://learn.microsoft.com/es-es/previous-versions/windows/desktop/legacy/ms644985(v=vs.85))
LowLevelKeyboardProc() never is executed
prompt that lparam is a pointer to a TKBDLLHOOKSTRUCT record.
Other ones however (http://www.delphifaq.com/faq/delphi_windows_API/f512.shtml and https://www.swissdelphicenter.ch/en/showcode.php?id=1722), show
function KeyHookFunc(Code, VirtualKey, KeyStroke: Integer): LRESULT; stdcall;
completely ignoring the TKBDLLHOOKSTRUCT record pointer.
Which one is correct?
I'm guessing the first one is the correct one but I need to be sure. I´ve been using such signature but when I call another Function in the same unit (and DLL) passing lParam it causes Access Violation when accessing it. All functions and procedures within the DLL use stdcall
All of the callback declarations are correct, although the latter two links do not give examples of LowLevelKeyboardProc but KeyboardProc. IOW, they are not low level keyboard hooks.
Note the latter two wouldn't work in 64 bits due to Integer usage instead of WPARAM, LPARAM and LRESULT.

Dynamicly handle not defined functions in a dll in dlephi

I have a dll which defines a simple functions to show a message:
library testdll;
uses SysUtils, Classes, Dialogs;
{$R *res}
procedure ShowDll;stdcall;
begin
ShowMessage('ShowDLL testdll.dll');
end;
exports ShowDLL;
begin
end.
And my main file call this dll dynamicly using this procedure:
i defined a new type:
type
testdll = procedure;stdcall;
Then on my button click event:
procedure TForm1.Button1Click(Sender:TObject);
var
dllHandle: THandle; //Don't use Cardinal; it's limited to 32-bits
test : testdll;
begin
dllHandle := LoadLibrary('testdll.dll');
if dllHandle <> 0 then
begin
#test := GetProcAddress(dllHandle,'ShowDLL');
if Assigned(test) then
ShowDLL
else
ShowMessage('Func not found');
end
else
ShowMessage('dll not found');
end;
This works. But I don't know if it's possible to handle not defined functions with my dll. My purpose here is to call a function without knowing if it will be defined in my dll. So i would like the dll to tell me if the functions exists or not.
For example here i only have a ShowDLL procedure. If i call another method which does not exists it will show 'Func not found' from my main application. But i would my dll to tell me this. Is this possible? If yes, how could i achieve this pls?
EDIT: I can't modify the main function this is only a test. In my final version there will be only the dll. So exporting all functions into my main application is not possible here. That's why i want to know id the dll alone can handle it rather than doing this in my main application which i can't do.
I don't have acces to the main application to modify any code in it. I only know what are functions that will be used in this application that i will later export in my dll using exports statement. So what i try to achieve is to catch a not defined function with the dll if it's possible.
Your code already demonstrates how to detect the presence of an export. Namely to call GetProcAddress and compare the result with nil.
You can reduce the amount of boiler plate code by using delay loading. This essentially lets the compiler generate the code the performs the checks. This relies on the delayed keyword.
procedure testdll; stdcall;
external 'testdll.dll` delayed;
When you call this function, if it cannot be found, an exception is raised. Indeed this behaviour can be customised, as described in the documentation: http://docwiki.embarcadero.com/RADStudio/en/Libraries_and_Packages#Delayed_Loading
Update
In a comment to this answer you state that the executable cannot be changed. In which case, the message that you wish to avoid will be shown if the function is missing. You ask if the missing export can be handled by the DLL but that is not possible. When you call GetProcAddress, no code inside the DLL is executed. All the processing is done external to the DLL by reading its PE metadata.
The obvious conclusion is that the DLL must export the function. If the true DLL does not, put another DLL in its place. Use an interposer DLL that exports the function. Implement the function by delegating to the true DLL, if the true DLL exports the function. Otherwise do something else, whatever you please.

Boolean parameter in a dll function in delphi 7

I have a dll library. I have excluded memory unit for delphi types.
In that way, what would be the appropriate Boolean type for function declaration?
Is it BOOL or something else?
The problem is that in the method signature:
function Test(Param1: BOOL; Param2: BOOL; docContent: PCharArray): Integer;
I get AV when program leaves that function.
I assume that it is the problem with the data type of these two first parameters.
BOOL is fine for Boolean types. It's a Windows type, so it's what you'll see in all the functions in Windows.pas.
Access violations upon return from a DLL function often indicate that you have the calling convention wrong — the default calling convention is register, but you probably need stdcall or cdecl. Add it at the end of the declaration:
function Test(Param1: BOOL; Param2: BOOL; docContent: PCharArray): Integer; stdcall;

Delphi DLL / Form communication

I have embedded a form in a DLL and can call the DLL and show the form and return various functions from the DLL back to the main app, however I cannot figure out how to get the DLL to trigger events in the main applications form.
For example in the main app I have a dataset and I want to have a button on the form in the DLL to goto a certain record in the dataset but cannot see how this is done.
Can anybody could point me to an example or give me some pointers on how to to this?
If a DLL needs to invoke behavior in the host application, then the host should provide a callback function to the DLL that the DLL stores and calls when appropriate.
Your DLL exports a function that tells it to display the form, right? Add a couple of parameters to that function for the EXE to provide a pointer to a callback function. The callback function should accept at least one parameter, which should be of type Pointer. The caller (the EXE) will use that parameter as a context parameter, some way for it to be reminded why the DLL is calling the EXE's function. Your DLL will store the function pointer and the context pointer, and when it's time for the DLL to tell the EXE something, it will call that function and pass the context value back. The DLL won't do anything with the context value; it's just something to store and pass back to the EXE verbatim.
The DLL's interface will look like this:
type
TDllCallback = function(Context: Pointer): DWord; stdcall;
function DisplayForm(Parent: HWnd; Callback: TDllCallback; Context: Pointer): DWord; stdcall; external Dll;
The EXE will define a callback function like this:
function CallbackFunction(Context: Pointer): DWord; stdcall;
begin
TMainForm(Context).DoSomething;
Result := 0;
end;
It will call the DLL function like this:
procedure TMainForm.DoDllTaskClick(Sender: TObject);
begin
DisplayForm(Handle, CallbackFunction, Pointer(Self));
end;
Notice how the signature of CallbackFunction matches the TDllcallback type defined earlier. Tey both use the stdcall calling convention, and they're both standalone functions, not methods. Avoid methods since method pointers are particular to Delphi, and you shouldn't require your DLL to be used only by Delphi hosts, if possible.
Because DLL's code being executed in the same address space of main application there are a plenty ways of doing communications.
Define a callback function in the main app and give its address to the DLL.
Define a message handler in the main app and send a message from DLL in response to some event.
etc.

Resources