Incorrect results given by LoadIcon, LoadCursor and LoadBitmap functions in a Windows environment.
Original Reporter info from Mantis: ChrisF
-
Reporter name:
Original Reporter info from Mantis: ChrisF
- Reporter name:
Description:
The LoadIcon, LoadCursor and LoadBitmap functions implemented in the graphics.pp unit are not fully compatible with the windows functions having the same names.
This is concerning only the case when the hInstance parameter is set to NULL, in order to get predefined icons, cursors and bitmaps from the windows system. See respectively:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648072%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/dd145033%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648391%28v=vs.85%29.aspx
The main problems are:
1/ If you declare 'windows' into your 'uses' clause, depending of the position of the 'windows' add into your 'uses' clause, it may be the windows.loadicon (loadcursor, loadbitmap) function which is called, or instead the graphics.loadicon (loadcursor, loadbitmap) one.
Without anyway to guess which one will be called during at runtime, except by "strong casting" them, as for windows.loadicon(...), for instance.
Furthermore there is absolutely no compilation error when 'windows' is added, though calling the graphics.loadicon (loadcursor, loadbitmap) this way should raised one. For instance:
MyCursorHandle:=LoadCursor(0,IDC_WAIT); // This one is invalid for graphics.loadcursor
According to my own tests (but I guess it may depends), when having 'windows' at the beginning of the 'uses' clause the graphics functions are called, while when having 'windows' at the end of the 'uses' clause, the windows functions are called.
2/ If the graphics functions are called with these kinds of call (i.e. hInstance=NULL, and predefined constant values in the lpResource name), an improper result is returned.
First, the current handle is not retrieved (as far as I can see, only the instance of the running application is valid for the concerned code, i.e. .LoadFromResourceName and .LoadFromResourceID methods).
Second, an exception is raised (see attached capture.png), while a null return value should be returned instead (if no handle is retrieved) in case of the windows api (no exception expected, even if the requested resource is not found).
Steps to reproduce:
-Start a new Lazarus/FPC graphic project (in a windows environment)
-Add 'windows' at the beginning of your 'uses' clause (or alternatively at the end; it mays depend),
-Add a new pushbutton into your form, and put this code for it:
procedure TForm1.Button1Click(Sender: TObject);
var i1: integer;
begin
i1:=LoadCursor(0,IDC_WAIT);
if i1=0 then
Button1.Caption:='Error'
else
Button1.Caption:='Is OK';
end;
-Run your project and click on the pushbutton. An exception is raised.
If you still can't get any exception when adding 'windows' at your 'uses' clause, you can still simulate the problem with the following conditions (this is only to simulate the problem explained here; this is not intend to be the problem by itself):
-Don't add 'windows' at your 'uses' clause,
-Put the current code for your pushbutton:
const IDC_WAIT=32514; // because this one is coming with 'windows.pp'
procedure TForm1.Button1Click(Sender: TObject);
var i1: integer;
begin
i1:=LoadCursor(0,PChar(Longword(IDC_WAIT)));
if i1=0 then
Button1.Caption:='Error'
else
Button1.Caption:='Is OK';
end;
Additional information:
The problem is that there are 2 kinds of functions with exactly the same name, and not the same behavior; and for the win32/win64 widgetset only.
Mantis conversion info:
- Mantis ID: 24222
- OS: Windows
- OS Build: XP
- Platform: i386-win32
- Version: 1.0.8
- Fixed in version: 1.1 (SVN)
- Fixed in revision: 41817 (#292d526f)