DialogBoxParam didn't work on 64-bit platform - delphi

I am porting my code to 64-bit platform.but I get a problem with DialogBoxParam.it work fine with 32-bit platform but not 64-bit.I used it like below
DialogBoxParam(Hinstance,MAKEINTRESOURCE(DLG_INPUTBOX),owner,#DialogProc,NativeInt(#info))
DLG_INPUTBOX come from the resource file
unit resource_gui;
interface
CONST
DLG_INPUTBOX = 8810;
DLG_PROGRESS = 8800;
DLG_AREYOUSURE = 8809;
BITMPAT_UNCHECKED = 8804;
BITMPAT_CHECKED = 8805;
{$R DLGRES.res}
here is the dialogpro
function DialogProc(hwndDlg:HWND;uMsg:UINT ;wParam:WPARAM ;lParam:LPARAM ):NativeInt;stdcall;
var
info:Pinfo;
OldEditValue:String;
CanClose:boolean;
begin
Result := EIINT(0);
case uMsg of
WM_INITDIALOG:begin
setWindowLong(hwndDlg,GWL_USERDATA,lParam);
end;
WM_SHOWWINDOW:begin
.......
I set a breakpoint in the WM_INITDIALOG code block but it didn't come in

See if this helps:
DialogBoxParam - works in win32, but doesn‎
I've been changing my code to 64 bit and came across my DialogBox Procedures. The call I made to DialogBoxParam to initialize the dialog box would no longer compile in 64 bit, so I changed my procedures from returning BOOL to returning INT_PTR.
Now when I run my code, my dialog box never shows up.
I put a break point in the DialogBox Procedure and it get:
WM_SETFONT
WM_DESTROY
WM_NCDESTROY
messages in that order. I never receive a WM_INITDIALOG message at all anymore!
My call to DialogBoxParam returns -1 and GetLastError returns 0
I had the exact same problem today. I found that my manifest file had the wrong processor architecture associated with it.
processorArchitecture="x86"
instead of
processorArchitecture="amd64"
Once I fixed that, the dialogbox popped up as expected.

Related

Explicit Loading of OpenSSL libcrypto-1_1.dll Issues

I've been using older OpenSSL libeay32.dll via explicit loading (LoadLibrary and GetProcAddress) in Delphi 10.2. Now I want to switch to the newer libcrypto-1_1.dll (compiled from OpenSSL 1.1.1i). The function BIO_read in test code below works fine with the libeay32.dll (value returned in 'w' is 256), however it fails with libcrypto-1_1.dll (value returned in 'w' is -1 and ERR_get_error returns 0). However, if I try to load the libcrypto-1_1.dll implicitly, the code below works fine.
Any ideas what goes wrong here? Maybe Delphi does something special, when it loads the library, so I've tried to find the place in Delhi's source code where Delphi loads the dll, but I did not find it. Anyone knows in which unit Delphi handles the implicit loading?
procedute Test;
var sigLen,r,w:integer;
base64Sig:TMemoryStream;
mem,b64,bio:pBio;
sig:pointer;
begin
base64Sig:=TMemoryStream.Create;
base64Sig.LoadFromFile(SignatureFileName);
mem:=BIO_new(BIO_s_mem);
b64:=BIO_new(BIO_f_base64);
bio:=BIO_push(b64,mem);
BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
r:=BIO_write(mem,base64Sig.Memory,base64Sig.Size);
writeln(r);
GetMem(sig,sigLen);
w:=BIO_read(b64,sig,sigLen);
writeln(w);
end;

Getting Delphi to read a database with a new version of Microsoft Access

We use a Delphi 10 programme that reads in an Access database. I do not deeply understand how it does it, except that I believe it uses units called DAO.pas and DAO_TLB.pas.
I recently upgraded from Office 2007 to Office 2016, and since then the Delphi programme is unable to read from the database; it gives the error:
Project MyProj.exe raised exception class EOleSysError with message 'Class not registered'.
I have tried to search to find how to fix this but am struggling because I don't really understand what's going on under the hood. I tried to install the Access 2016 type library, but that didn't seem to make any difference.
Extremely grateful for any help.
Thanks,
Tom
EDIT: DAO.pas is here. DAO_TLB.pas is where the error is triggered; the function which errors is:
class function CoDBEngine.Create: _DBEngine;
begin
Result := CreateComObject(CLASS_DBEngine) as _DBEngine;
end;
Where CLASS_DBEngine is a constant declared as:
CLASS_DBEngine: TGUID = '{CD7791B9-43FD-42C5-AE42-8DD2811F0419}';
I have also just noticed that, when the error occurs, if I click continue rather than break, a new error appears, saying:
Class not registered, ClassID: {CD7791B9-43FD-42C5-AE42-8DD2811F0419}
i.e. the ClassID is the CLASS_DBEngine constant.

How do I avoid the debugger stopping my program when browsing a non-image in a TOpenPictureDialog?

I'm using a TOpenPictureDialog to browse for images. In debug mode, when I'm browsing in this dialog for a picture and I happen to click (not double click) on a shortcut (.lnk), the debugger interrupts my program because it catches an exception, saying it's not a valid file format.
How to overcome this? I know it's only in debug time and don't have any issue in the final EXE, but it is getting very annoying, because I'd like to be able to go through these shortcuts.
You are out of luck here, this bug was reported in the QC 69533 and was fixed in the update 3 of Delphi 2009.
The code used to by the VCL to verify if a file is valid image, doesn't check for the shortcuts files (.lnk) so the VCL thinks which the file is a valid image and try to load the file and then raises a EInvalidGraphic exception.
The exception is only raised in the debugger because a code like this is used to check the validate the filename.
(Only showing part of the real code because is VCL code)
ValidPicture := FileExists(FullName) and ValidFile(FullName);
if ValidPicture then
try
// here try to load the file even if is a shortcut(.lnk)
except //this exception is caught by the debugger.
ValidPicture := False;
end;
Workarounds
1) You can add the EInvalidGraphic exception, to the exceptions list to ignore list.
2) you can write a detour (here you have a sample) and implement your own TOpenPictureDialog.DoSelectionChange method (validating the .lnk files), because is here where is made the validation of the files to load.
3) you can override the DoSelectionChange method of the TOpenPictureDialog using a interposer class, to validate the files to load.
TOpenPictureDialog= class (ExtDlgs.TOpenPictureDialog)
procedure DoSelectionChange; override;
end;

Access violation in delphi

In a delphi Application, When I move mouse to a component that has Hint I see this error :
" Access violation at address 00484F3B in module 'Plibrary.exe'. Read of address 0000026C"
Why this happen?
Call Stack:
:758e9617 KERNELBASE.RaiseException + 0x54
:458bf456 System.#UStrCmp
:00407558 #UStrCmp + $2C
Forms.TApplication.SetHint(???)
Forms.TApplication.Idle(???)
Forms.TApplication.HandleMessage
Forms.TApplication.Run Plibrary.Plibrary
:75ca1194 kernel32.BaseThreadInitThunk + 0x12
:7752b3f5 ntdll.RtlInitializeExceptionChain + 0x63
:7752b3c8 ntdll.RtlInitializeExceptionChain + 0x36"
And failing code is in System.pas file at line 17732 : "MOV ESI,[ESP]"
Edit (from comment):
In the remain.pas file at this procedure :
procedure TMainForm.ShowHint(Sender: TObject);
begin
if Length(Application.Hint) > 0 then begin
StatusBar.SimplePanel := True;
StatusBar.SimpleText := Application.Hint; //this line gives error
end else
StatusBar.SimplePanel := False;
end;
Read of address 0000026C
This very low address is indicative of an offset to a member field of a nil object reference. Run under the debugger and make sure the debugger is set to break on exceptions. When it does, you should be able to work out which object reference is nil.
Quite possibly the AV happens in VCL code although it will almost certainly be due to an error in your code. If the debugger doesn't break at a very helpful location, enable Debug DCUs in the project options in order to see the VCL source code at the point where the exception is raised.
The stack trace you provide suggests that the error is in TApplication.SetHint, whilst performing a string comparison. The first line of TApplication.SetHint reads:
if FHint <> Value then
I bet the offset to the FHint of TApplication is $026C and that, somehow, your Application variable is set to nil. That said, I don't understand why the error would not have been raised earlier at Length(Application.Hint). It's quite hard to debug this remotely!
Having looked at the layout of TApplication, I think we can rule out Application being nil. Perhaps FHint itself has somehow been corrupted, or perhaps even Value. I think it's going to take access to the actual code and a debugging environment to track this down.
Based on the information provided in the stacktrace:
TApplication.Idle:
Control := DoMouseIdle;
if FShowHint and (FMouseControl = nil) then
CancelHint;
Application.Hint := GetLongHint(GetHint(Control)); // SetHint is called next:
TApplication.SetHint:
if FHint <> Value then // This is the UStrCmp which fails with a Int overflow
String + IntOverflow -> non terminating string. So the most probable cause is a string without a terminator.
So where does the string come from...
GetHint(Control) searches the control (which is at the places you clicked with the cursor) and its parent for a hint that is not empty.
GetLongHint searches the string for a | and if found, uses the part following the | else it uses the complete string.
UStrCmp, is a long pieces of assembler code, that calls other pieces of assembler code. Some of them can raise the EIntegerOverflow error.
Advise
Use the debugger (with debug dcu's on) to see which string has no terminator (0 character at the end). And if you find it, try to solve it or expand the question if you want some more help from us.

RLINK32: Error opening file "...\Data.DFM". Occurs the first time I build a project after opening Delphi

I get this error the first time I build/compile a particular project after opening Delphi (D6 Pro). Subsequent builds do not give the error.
I have the same issue, it was fixed by replacing {$R *.dfm} directive in the problem unit (which was not found by Delphi during first compilation) by more specific clause {$R fMain.dfm}.
The error can be caused by an exception being raised in a design component on the form. If the component is running some initialisation code which raises an exception this error will be produced. This can be shown by adding
raise Exception.CreateFmt('Test', []);
into the code of the component. Note that in D6 Pro this does not produce 'Test' in the error message. The underlying exception message is not displayed.
This is probably caused by a control that raises an exception during its creation (when the form is loaded).
How I solved this (this case was specific for me, but a very similar solution may apply to you):
First I loaded the 'broken' unit into the IDE. It didn't caused an error until I pressed F12 to see the form. The error message raised by the IDE was not very helpful, but after changing the {$R *.dfm} to {$R MainForm.dfm}, the error message changed to something more specific. More exactly, in the error report, one line was of special interest:
{MyControls_XE.bpl} StrGrdBase.TBaseStrGrid.FixCursor (Line 569, "StrGrdBase.pas" + 9) + $8
I navigated to that line and I have seen that in some conditions I was trying to set focus on the second row, while the grid had only one row.
I also got the same error on Deplhi 2010, the problem was there was a component which has not been installed in IDE, when I changed the component to the one that exists it is worked as a charm.
I've found an additional reason for this behaviour: DFM files are rejected if a property is placed below any child objects owned by the main object. In other words, a TButton object should be defined below the last property of the TPanel object that the button is placed on. Tested with D2010, compiling with bcc32

Resources