News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Gdi Open Image

Started by guga, December 18, 2012, 11:46:33 PM

Previous topic - Next topic

guga

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 )-
Image Fail - Once i changed the folder (uped a directory there is an error on drawing the opendialog)
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

dedndave

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

dedndave

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

guga

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
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

guga

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)
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

qWord

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?
MREAL macros - when you need floating point arithmetic while assembling!

guga

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.

Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

dedndave

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 ?

MichaelW

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.
Well Microsoft, here's another nice mess you've gotten us into.

guga

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.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

jj2007

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?

guga

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.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

guga

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'
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com