Gdi Open Image
convertion and fix of gdiptest by dougiem0305
It can load jpg, bmp, png, gif, etc images.
There is a problem when changing the folder when you open an image (opendialog). Strange behaviours shows up, and i can´t fix it right now. If someone knows how to fix it, please let me know
I attached the original masm files from dougiem0305. And inside the exe, i modified the hook function for opendialog, but it still have errors
as image below:
Image ok (Preview not show here...becauise i didn´t clicked the image )- (http://i46.tinypic.com/357odb4.jpg)
Image Fail - Once i changed the folder (uped a directory there is an error on drawing the opendialog) (http://i45.tinypic.com/ipcbqq.jpg)
i am guessing your hook callback isn't returning the proper value
QuoteIf the hook procedure returns zero, the default dialog box procedure processes the message.
If the hook procedure returns a nonzero value, the default dialog box procedure ignores the message.
For the CDN_SHAREVIOLATION and CDN_FILEOK notification messages, the hook procedure should return a nonzero value to indicate that it has used the SetWindowLong function to set a nonzero DWL_MSGRESULT value.
for some messages you handle, you may also want the default handling
i am able to change folders, but the scroll bar looks strange at first :P
it fixes itself after i preview a couple images - weird
Hi dave
yeah, i saw it too. I have no idea what i´m doing wrong.
I found sme examples on codeproject that may help...I´ll take a lok tonight when i come home.
http://www.codeproject.com/Articles/16069/SHBrowseForFolder-with-Explorer-style-file-open-di
http://www.codeproject.com/Articles/19566/Extend-OpenFileDialog-and-SaveFileDialog-the-easy
http://www.codeproject.com/Articles/29/Customizing-the-Windows-Common-File-Open-Dialog
there a leak somewhere
if i replace all the gdiplus call to C_call gdi will crash
Ex: C_call 'gdiplus.GdipDisposeImage' D$GpvImage
Where:
[C_call | &9=0 | C_Call2 #1 #L>2]
[C_Call2 | &9=&9+4 | push #2 | #+1 | call #F | add esp &9]
If i make the calls to gdi apis as the same way we do for wsprintF (withe the fix for the stack pointer), the app will crash. Somewhere is having a stack problem (internally gdi api or in my code)
Quote from: guga on December 19, 2012, 01:30:11 AM
if i replace all the gdiplus call to C_call gdi will crash [...]
Somewhere is having a stack problem
did you really expect that this works?
No, i´m trying to find if there was an stack point error somewhere inside gdi api
The usage of the macro was to adjust the stack to scan for errors. If all parameters are Ok, the usage of C_call macro will not change anything, since it will always be adjusting the stack properly. On a normal app, this will never crash, except if somewhere there is an leak or stack problem somewhere.
Using the C_call macro for error scanning lead me here:
Proc ShowPreview:
; test for text in window
call 'user32.GetDlgItem' D$sDlg, &EDT1
call 'user32.SendMessageA' eax, &WM_GETTEXT, 80, Edbuffer
On eax = 0, ExitP
; here we check the check box and skip draw image
mov eax 1
On D$chkState = 0, ExitP
call 'kernel32.MultiByteToWideChar' &CP_ACP, 0, Edbuffer, 0-1, uEdbuffer, 160
C_call 'gdiplus.GdipLoadImageFromFile' uEdbuffer, GpvImage
.If eax <> 0
; detects a wrong filename comming to preview
C_call 'gdiplus.GdipGraphicsClear' D$GpvGraphics, D$BkGrnd
call 'user32.SetWindowTextA' D$hTxt1, 0
xor eax eax
.Else
; 'fill/fit' preview win (same as in winproc)
C_call 'gdiplus.GdipGraphicsClear' D$GpvGraphics, D$BkGrnd
C_call 'gdiplus.GdipGetImageWidth' D$GpvImage, pvW
C_call 'gdiplus.GdipGetImageHeight' D$GpvImage, pvH
call 'user32.SetRect' vsrc, 0, 0, D$pvW, D$pvH
call 'user32.SetRect' vdst, 0, 0, 90, 70
call AdjustRcToFit vdst, vsrc, 0
call DrawImageRectsIP D$GpvGraphics, D$GpvImage, vdst, vsrc
C_call 'gdiplus.GdipDisposeImage' D$GpvImage <------------- here it crashed when i click on a file to be loaded
mov eax &TRUE
.End_If
EndP
C_call 'gdiplus.GdipDisposeImage' D$GpvImage <------------- here it crashed when i click on a file to be loaded
I´m not sure if the crash is due to the macro itself that cannot handle only 1 parameter....Or if is somewhere inside gdi api.
The debugger accuses the eip as having a value of 046 "70" when returning the call. Probably it hve nothing to do wiuth the usage of C-call randomnly, but i´m not at home right now for test, i´m just guessing.
that may indicate that the image handle is still in use by another function or operation
although, i would expect it to return an error rather than crash :P
hang on....
are you passing the handle or a pointer to the handle ?
isn't it supposed to be a pointer to the handle ?
another possibility...
what is the scope of the handle - is it local or global ?
Quote from: guga on December 19, 2012, 01:30:11 AM
if i replace all the gdiplus call to C_call gdi will crash
How can this work otherwise? You have previously posted code that used C_call with wsprintfA, but that function uses the C calling convention. GDI+ uses stdcall, so the called procedure removes the parameters from the stack on return. If the C_call macro is removing the parameters after the call has returned, as per the C calling convention, then the stack pointer will be off by the number of bytes in the parameters.
Hi Michael. yeah i know, but the macro is not the problem. I was trying to determine if there was a leak in gdi or a stack error somewhere else. I wasn´t sure that all gdi apis was using stdcall. So i just replaced all with the macro to see where it hangs and if the hang was worthfull for something.
But, the problem seems to be not on the stack (of all apis including gdi+ ones), but it seems that it is a gdi leak somewhere. I removed the c_call macro from gdi and settled hook function to handle CDN_SHAREVIOLATION and the problems seems to be still there.
The image in memory seems to not be properly released, causing the leak. I started to search for a proper way to initialize and release Gdi+ memory.
Hi Guga,
Just to let you know that I can't produce any strange behaviour on WinXP SP3. Nice app, by the way - simple and elegant :t
Does the bad behaviour show immediately after a reboot?
Hi JJ
"Nice app, by the way - simple and elegant :t"
many thanks :)
On the original masm version, dougiem0305 made a good work on the gdi, although it still had problems before i fixed (it was designed for win98, i guess. This is why his masm version behave more strangelly on my PC when i open the opendialog box). Also, it had a mistake in one of the Guids. He used GUID_ImageFormatIcon as starting with "0B96B3CB3", but, in fact this Dword is related to GUID_ImageFormatPhotoCD. So i fixed the Guids as below:
[GUID_ImageFormatUndefined: D$ 0B96B3CA9, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E
GUID_ImageFormatMemoryBMP: D$ 0B96B3CAA, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E
GUID_ImageFormatBMP: D$ 0B96B3CAB, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E
GUID_ImageFormatEMF: D$ 0B96B3CAC, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E
GUID_ImageFormatWMF: D$ 0B96B3CAD, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E
GUID_ImageFormatJPEG: D$ 0B96B3CAE, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E
GUID_ImageFormatPNG: D$ 0B96B3CAF, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E
GUID_ImageFormatGIF: D$ 0B96B3CB0, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E
GUID_ImageFormatTIFF: D$ 0B96B3CB1, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E
GUID_ImageFormatEXIF: D$ 0B96B3CB2, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E
GUID_ImageFormatPhotoCD: D$ 0B96B3CB3, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E
GUID_ImageFormatFlashPix: D$ 0B96B3CB4, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E
GUID_ImageFormatIcon: D$ 0B96B3CB5, W$ 0728, W$ 011D3, B$ 09D, 07B, 0, 0, 0F8, 01E, 0F3, 02E]
About the behavious in my machine, it is weird, i also have here WinXp Sp3 and the error is still here. I rebooted and the problem remains. I´[m looking for a fix, but it seems to me a weird gdi memory leak error somewhere.
My goal is to make a small app able to edit an image, apply some effects etc (grayscale, rotate, pixelate, blur, unblur etc). I want something similar to AbitmapEditor from Darrel, but simpler. I don´t have his source to analyse his work (would make all much simpler), but if someone have his source, please let me know.
OK, i guess i found the problem
It seems to be as dedndave suggested a problem with the handles. In fact, it seems that i need to initialize and shutdown the gdi for the different situations it is being used.
Both preview and loading share the same object, but with different handles, but i need to shutdown the image just after using it on the opendialog preview. So i´ll probably need to initialize and shutdown the image object used to it´s own handle.
I´m not sure if i can have the same graphic object assigned to more then 1 handle ate the same time.
I´ll make further tests, but most likely i´ll need to completely destroy the gdi graphics object and handle related to the Preview mode in the OpenFile dialog. Or, if i can use the same graphic object in both situations, i´ll probably need to delete the handle related to the dialog preview.
Personally i´ll try to isolate it and make this graphic object be used only with the preview mode, specially if i (or other users) intend to make a sort of custom control dll. For example, i´ll probably make a dll that can be used simply as
call 'Mydll.GdiOpenFile'