Hello people;
I have attached a project which loads an animated GIF using AniGIF library.
We should include the library
Include AniGIF.inc
IncludeLib AniGIF.lib
PUBLIC hInstance
Very important to declare hInstance as PUBLIC!!
Under Window procedure call two functions
PencereIslemi proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
invoke InitAniGIF ;Starts animation
mov eax,uMsg
.if eax==WM_INITDIALOG
.
.
.
.
.elseif eax==WM_COMMAND
.
.
.
.
.elseif eax==WM_CLOSE
.
.
.else
mov eax,FALSE
ret
.endif
invoke TerminateAniGIF ;HERE terminates animation
mov eax,TRUE
ret
PencereIslemi endp
Very important part :
#define logoGif 501
logoGif RCDATA DISCARDABLE "Res/nelieltransform.gif"
CONTROL "#501",aniLogo,"AniGIF",0x50000000,6,3,333,184,0x00000000
You have to write down "AniGIF" to Control section
And you have to define GIF as RCDATA
I want to ask is there any other options to achieve this goal without using these external -AniGIF- libraries?
@jj2007 you have included executables several times to forum. Bu you didnt share any source codes about this issue. Are you also using this libraries? If not can you share any sources with me?
Thanks for all =)
Because of the GIF file the zip file size is ~700kb So here is a link to Github and Zippyshare
https://github.com/blue-devil/Assembly/tree/master/RadASM/Masm/Projects/GifView
http://www118.zippyshare.com/v/Nwse3uPN/file.html
Quote from: blue_devil on May 18, 2017, 02:31:14 AM@jj2007 you have included executables several times to forum. Bu you didnt share any source codes about this issue. Are you also using this libraries? If not can you share any sources with me?
No, I use only the built-in Windows library GdiPlus. Here is a source:
guiTimerMs=50 ; more is slower
GuiParas equ "Simple GIF viewer", w240, h200
include \masm32\MasmBasic\Res\MbGui.asm ; part of MasmBasic (http://masm32.com/board/index.php?topic=94.0)
Event Paint
.if CL$(?)
GuiImage CL$(), fit ; drag an animated gif over the exe
.else
GuiImage 100, fit ; or show tweetie from the resources
.endif
GuiEndFull project attached, needs MasmBasic (http://masm32.com/board/index.php?topic=94.0), of course.
\masm32\MasmBasic\Res\MbGui.asm is a public part of MasmBasic; the rest is closed source, but I could give you a personal exclusive license to disassemble the closed part, if you give me a good reason :bgrin:
For example, you could insert an
int 3 into line 15572 of \Masm32\MasmBasic\MasmBasic.inc ;)
Quote from: jj2007 on May 18, 2017, 04:41:16 AM
Quote from: blue_devil on May 18, 2017, 02:31:14 AM@jj2007 you have included executables several times to forum. Bu you didnt share any source codes about this issue. Are you also using this libraries? If not can you share any sources with me?
No, I use only the built-in Windows library GdiPlus. Here is a source:
guiTimerMs=50 ; more is slower
GuiParas equ "Simple GIF viewer", w240, h200
include \masm32\MasmBasic\Res\MbGui.asm ; part of MasmBasic (http://masm32.com/board/index.php?topic=94.0)
Event Paint
.if CL$(?)
GuiImage CL$(), fit ; drag an animated gif over the exe
.else
GuiImage 100, fit ; or show tweetie from the resources
.endif
GuiEnd
Full project attached, needs MasmBasic (http://masm32.com/board/index.php?topic=94.0), of course.
\masm32\MasmBasic\Res\MbGui.asm is a public part of MasmBasic; the rest is closed source, but I could give you a personal exclusive license to disassemble the closed part, if you give me a good reason :bgrin:
For example, you could insert an int 3 into line 15572 of \Masm32\MasmBasic\MasmBasic.inc ;)
1. As a MASM32 coder i cannot understand your way of codes. In my MASM directory i have a MasmBasic directory too. But it says:
Quote; The smallprint: this library is provided "as is", and the usual disclaimers apply.
; This help file refers to MasmBasic version 4 October 2012
; -----------------------------------------------------------------------
include \masm32\MasmBasic\MasmBasic.inc ; this line substitutes include \masm32\include\masm32rt.inc
Is this old or very old version?
2. What is .ASC file doing exactly?
3. Generally hutch-- gives more pure assembly samples. But i always open to new knowledge. But here i have 2 issues.
3.a. I want to learn assembly, all syntaxes, rules, constants and everything. And in a very low-level way
3.b. I want to use RadASM as an IDE because i am the guy translated it in Turkish so i know every part of it.
4.When i see your code above i cannot implement that inside my own code :( Because i cannot understand what GuiImage does, what CL does and what $ does after CL?
5.At the end there must be a windows API but i still couldn't get there :(
Quote from: blue_devil on May 18, 2017, 05:58:57 AM
1. As a MASM32 coder i cannot understand your way of codes. In my MASM directory i have a MasmBasic directory too. But it says:
Quote; The smallprint: this library is provided "as is", and the usual disclaimers apply.
; This help file refers to MasmBasic version 4 October 2012
; -----------------------------------------------------------------------
include \masm32\MasmBasic\MasmBasic.inc ; this line substitutes include \masm32\include\masm32rt.inc
Is this old or very old version?
Almost five years old. Incredibly old. How old is your current smartphone? The current MasmBasic version is dated 12 May 2017 (http://masm32.com/board/index.php?topic=94.0). But caution, installing MasmBasic is incredibly complicated. Well, actually not
that complicated, maybe installing GCC or VS Community can give you even more headaches ::)
Quote2. What is .ASC file doing exactly?
Assembler
Source
Code. Extract AnimatedGifViewer.asc and Tweetie.gif to any folder, then open the *.asc in \Masm32\MasmBasic\RichMasm.exe and hit the F6 key. The two files in the zip are the complete project.
Quote3. Generally hutch-- gives more pure assembly samples. But i always open to new knowledge. But here i have 2 issues.
3.a. I want to learn assembly, all syntaxes, rules, constants and everything. And in a very low-level way
Hutch is a very good at low level assembler, but he is equally good at writing macros and high-level library functions, see \masm32\help\masm32.chm
The question "is pure low level assembler better than using macros?" is very important in the early stages of learning. Later on, you will still be able to write low level assembler, but if you don't use macros, you will never go significantly beyond the hello world proggie stage. If you wonder what "significantly" means: The source of the RichMasm editor is currently close to 20,000 lines. That is a medium size program.
Theoretically, one could write such a program in push push call style, have fun.
Quote3.b. I want to use RadASM as an IDE because i am the guy translated it in Turkish so i know every part of it.
It
should be is possible
*) to use MasmBasic from RadASM - after all, it's assembler, in the sense of: ML.exe can digest a MasmBasic source, from version 6.15 onwards.
I haven't tested it, though (and I prefer HJWasm for building my stuff). Has anybody tested using MB in RadASM?Quote4.When i see your code above i cannot implement that inside my own code :( Because i cannot understand what GuiImage does, what CL does and what $ does after CL?
5.At the end there must be a windows API but i still couldn't get there :(
There is a MasmBasic manual, and there is one for OllyDbg, too.
*) RadAsm assembles the source without problems, but convincing the IDE to add the resource and compile it is a major challenge :dazzled: In the end, I gave up with the *.rc file, instead I copied the rsrc.res from the MasmBasic folder and changed the linker's commandline by hand, adding rsrc.res. The full RadASM project is attached.
blue_devil ,
a short demonstration using Gdiplus. See msdn for deatils of the used functions. Requires foo.gif in current dir and cmd option /Zp8
include \masm32\include\masm32rt.inc
include \masm32\include\gdiplus.inc
includelib \masm32\lib\gdiplus.lib
.686
.data?
hInstance HINSTANCE ?
.code
WndProc proto hWnd:HWND,uMgs:UINT,wParam:WPARAM,lParam:LPARAM
main proc
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL gsi:GdiplusStartupInput
LOCAL gtkn:PULONG
mov gsi.GdiplusVersion,1
mov gsi.DebugEventCallback,0
mov gsi.SuppressBackgroundThread,0
mov gsi.SuppressExternalCodecs,0
invoke GdiplusStartup,ADDR gtkn,ADDR gsi,0
mov hInstance,rv(GetModuleHandle,0)
mov wc.hInstance,eax
mov wc.cbSize,SIZEOF wc
mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_SAVEBITS
mov wc.lpfnWndProc,OFFSET WndProc
mov wc.cbClsExtra,0
mov wc.cbWndExtra,0
mov wc.hIcon,rv(LoadIcon,0,IDI_APPLICATION)
mov wc.hIconSm,eax
mov wc.hCursor,rv(LoadCursor,0,IDC_ARROW)
mov wc.lpszMenuName,0
mov wc.hbrBackground,0
mov wc.lpszClassName,chr$("Win32Wnd")
invoke RegisterClassEx,ADDR wc
mov ebx,ASM(mov edi,rv(GetSystemMetrics,SM_CXSCREEN))
mov ecx,rv(GetSystemMetrics,SM_CYSCREEN)
shr ebx,1
shr eax,1
shr edi,2
shr ecx,2
fnx esi = CreateWindowEx,0,wc.lpszClassName,"Foo32",WS_VISIBLE or WS_SYSMENU or WS_MAXIMIZEBOX or WS_MINIMIZEBOX or WS_SIZEBOX,edi,ecx,ebx,eax,0,0,hInstance,0
invoke UpdateWindow,esi
.while 1
invoke GetMessage,ADDR msg,0,0,0
.break .if !eax || eax == -1
invoke TranslateMessage,ADDR msg
invoke DispatchMessage,ADDR msg
.endw
invoke GdiplusShutdown,gtkn
invoke ExitProcess,msg.wParam
main endp
getDelayProp proc image:PVOID
LOCAL propSize:UINT
LOCAL delayProp: ptr PropertyItem
invoke GdipGetPropertyItemSize,image, PropertyTagFrameDelay, ADDR propSize
mov delayProp,alloc(propSize)
invoke GdipGetPropertyItem,image, PropertyTagFrameDelay, propSize, delayProp
mov eax,delayProp
ret
getDelayProp endp
getFrameCount proc image:PVOID, dimGuid: ptr GUID
LOCAL dimCount:DWORD
LOCAL dimensionIDs: ptr GUID
LOCAL count:DWORD
invoke GdipImageGetFrameDimensionsCount,image, ADDR dimCount
.if eax || dimCount != 1
xor eax,eax
ret
.endif
imul edx,dimCount,SIZEOF GUID
mov dimensionIDs,alloc(edx)
invoke GdipImageGetFrameDimensionsList,image,dimensionIDs, dimCount
invoke GdipImageGetFrameCount,image,dimensionIDs,ADDR count
invoke RtlMoveMemory,dimGuid,dimensionIDs,SIZEOF GUID
free dimensionIDs
mov eax,count
ret
getFrameCount endp
getDelayForFrame proc delayProp:ptr PropertyItem, frameNo:DWORD
mov edx,delayProp
assume edx: ptr PropertyItem
mov ecx,[edx]._length
.if [edx].nType == PropertyTagTypeLong ||[edx].nType == PropertyTagTypeSLONG
shr ecx,2
.elseif [edx].nType == PropertyTagTypeShort
shr ecx,1
.elseif [edx].nType != PropertyTagTypeByte
; error case
int 3
.endif
.if ecx < frameNo
; error case
int 3
.endif
mov ecx,[edx].value
mov eax,frameNo
.if [edx].nType == PropertyTagTypeLong ||[edx].nType == PropertyTagTypeSLONG
mov eax,DWORD ptr [ecx + DWORD*eax]
.elseif [edx].nType == PropertyTagTypeShort
movzx eax,WORD ptr [ecx + WORD*eax]
.else
movzx eax,BYTE ptr [ecx + eax]
.endif
assume edx: nothing
imul eax,10 ; GIF delay unit is 1/100s => mul. with 10 to get milliseconds
ret
getDelayForFrame endp
WndProc proc uses ebx esi hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL rect:RECT
LOCAL ps:PAINTSTRUCT
LOCAL graphics:PVOID
.data?
gifImage PVOID ?
delayProp PVOID ? ; ptr PropertyItem
frameCount SDWORD ?
frameDimGuid GUID <>
frameNumber SDWORD ?
.code
.if uMsg == WM_CLOSE
invoke PostQuitMessage,0
.elseif uMsg == WM_DESTROY
invoke GdipDisposeImage, gifImage
free delayProp
.elseif uMsg == WM_CREATE
fnx GdipLoadImageFromFile,L"foo.gif", ADDR gifImage
fnx delayProp = getDelayProp,gifImage
fnx frameCount = getFrameCount,gifImage,ADDR frameDimGuid
.if frameCount > 1
add frameNumber,1
invoke getDelayForFrame,delayProp,frameNumber
invoke SetTimer,hWnd,123,eax,NULL
.endif
.elseif uMsg == WM_TIMER && wParam == 123
invoke KillTimer,hWnd,123
invoke GdipImageSelectActiveFrame,gifImage, ADDR frameDimGuid, frameNumber
mov eax,frameNumber
add eax,1
.if eax == frameCount
xor eax,eax
.endif
mov frameNumber,eax
invoke getDelayForFrame,delayProp,eax
invoke SetTimer,hWnd,123,eax,NULL
invoke InvalidateRect,hWnd,NULL,FALSE
.elseif uMsg == WM_PAINT
invoke BeginPaint,hWnd,ADDR ps
invoke GetClientRect,hWnd,ADDR rect
fnx ebx = CreateCompatibleDC,ps.hdc
invoke CreateCompatibleBitmap,ps.hdc,rect.right,rect.bottom
fnx esi = SelectObject,ebx,eax
invoke GdipCreateFromHDC,ebx, ADDR graphics
invoke GdipGraphicsClear,graphics,-1
invoke GdipDrawImageI,graphics, gifImage,0,0
invoke BitBlt,ps.hdc,0,0,rect.right,rect.bottom,ebx,0,0,SRCCOPY
invoke DeleteObject,rv(SelectObject,ebx,esi)
invoke DeleteDC,ebx
invoke GdipDeleteGraphics,graphics
invoke EndPaint,hWnd,ADDR ps
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
end main
BTW: What has happen to this forum? "Use masmbasic" is now the accepted default answer to any upcoming question?
i remember there was static gif lib, no ani gif lib.
Quote from: qWord on May 18, 2017, 11:35:28 AMBTW: What has happen to this forum? "Use masmbasic" is now the accepted default answer to any upcoming question?
OP asked explicitly how I did it. Apart from this post, I made a quick check and found out that my last 28 posts had nothing to do with MasmBasic. So your remark proves that you are German and nothing else. Btw you should try MasmBasic, much faster than C and (no) [ugly] {brackets} or se;mi;co;lons; 8)
Quote from: qWord on May 18, 2017, 11:35:28 AM
and cmd option /Zp8
Hi qWord, thanks for the example, just wondering why the /Zp8 is required? is it some alignment with data structures or for the gif file. Thanks in advance
Hi qWord!
Without /Zp I have a crash in: mov eax,DWORD ptr [ecx + DWORD*eax]
in theory is a 4 bytes problem. And work perfect with /Zp4 :t
qword,
I am not sure why but after building it with the /Zp8 option and placing an animated gif in the same directory, it builds with no errors but will not run. Ends up in memory but nothing shows.
Quote from: fearless on May 18, 2017, 10:45:04 PMjust wondering why the /Zp8 is required?
It the default structure member alignment in Win32 and should be always used to avoid strange errors. For most structures it has no effect because of their layout. In the above example it is the PropertyItem structure that has a WORD-sized member breaking the alignment of the following pointer (and yes, for this structure also Zp4 works, because there are no 64 bit width members in it)
Quote from: jj2007 on May 18, 2017, 04:40:11 PM
OP asked explicitly how I did it.
He explicit ask how do it with plain WinAPI.
Quote from: jj2007 on May 18, 2017, 04:40:11 PMApart from this post, I made a quick check and found out that my last 28 posts had nothing to do with MasmBasic.
just ignoring the several thousand other post you did with more or less "advertising".
Quote from: jj2007 on May 18, 2017, 04:40:11 PMSo your remark proves that you are German and nothing else
Yes Mr. "I know the answer, but I won't give it to you"
Quote from: hutch-- on May 19, 2017, 12:30:09 AM
I am not sure why but after building it with the /Zp8 option and placing an animated gif in the same directory, it builds with no errors but will not run. Ends up in memory but nothing shows.
strange - can you upload the EXE?
Attached my build.
Just tried your build, will not run on my Win10 64 bit.
I have attached the source and how I built it and used your GIF file.
I could not get your window to start so I put all of your GDIP code in another window but it was looking for code that was not available. Are you using a special GDI plus include file ?
Your build works fine on win7x64
I guess there is some incompatibility in my code - would require to analyze the return values of the GDIP functions. I will try it later with a Win10 dev VM.
Quote from: hutch-- on May 19, 2017, 01:12:37 AMAre you using a special GDI plus include file ?
Actual not.
Quote from: hutch-- on May 19, 2017, 01:12:37 AM
Just tried your build, will not run on my Win10 64 bit.
On Win10, CreateWindowEx fails with invalid menu handle.
On Win7-64, the OS set esi initially to zero, so this succeeds:
fnx esi = CreateWindowEx,0,wc.lpszClassName,"Foo32",WS_VISIBLE or WS_SYSMENU or WS_MAXIMIZEBOX or WS_MINIMIZEBOX or WS_SIZEBOX,edi,ecx,ebx,eax,0,
esi,hInstance,0
And in any case,
mov ecx,[edx].value will fail unless the linker is explicitly told to align the structure. The problem is lack of a padding word in Windows.inc (the default Masm32 strategy) for that structure.
Quote from: jj2007 on May 19, 2017, 01:48:41 AM
On Win10, CreateWindowEx fails with invalid menu handle.
On Win7-64, the OS set esi initially to zero, so this succeeds:
fnx esi = CreateWindowEx,0,wc.lpszClassName,"Foo32",WS_VISIBLE or WS_SYSMENU or WS_MAXIMIZEBOX or WS_MINIMIZEBOX or WS_SIZEBOX,edi,ecx,ebx,eax,0,esi,hInstance,0
yes, thats it.
I did JJ's mod and it was still failing but not ending up in memory.
Commented out this section in the WM_CREATE,
; .if frameCount > 1
;
; add frameNumber,1
;
; invoke getDelayForFrame,delayProp,frameNumber
; invoke SetTimer,hWnd,123,eax,NULL
;
; .endif
And the Window appears with the gif image but of course no animation.
This is the ML command line in the batch file.
\masm32\bin\ml /c /coff /Zp8 "qword_gdip.asm"
I currently have ML version 14 running.
Quote from: hutch-- on May 19, 2017, 02:15:00 AM
I did JJ's mod and it was still failing but not ending up in memory.
Yes, sometimes it ends up in no man's land. But most of the time it works in Win10 with an xor esi, esi.
Hello everyone;
1. I also cannot managed to run on Win10x64. I am stuck like hutch--.
2. @jj2007, i attach my version on your codes please check it out. It is working, but not perfect. Try the other gif files in the zip package. If the gif file is rectangular or square, it is ok. But if it has some kinda transparent background, it show improperly. BTW jj2007 i admire your work on MasmBasic, i will spend on time with that. But my approach is more on reverse engineering so i want to learn winapi and masm/assembly much deeply. On the contrary, masmbasic is really practical and very good if you develop or solve problems. But ineed deep understanding of the system.
3. So i will go an anigif library guys. If someone find a solution, i am here to listen.
Quote from: blue_devil on May 26, 2017, 10:33:17 PMIf the gif file is rectangular or square, it is ok. But if it has some kinda transparent background, it show improperly. BTW jj2007 i admire your work on MasmBasic
Thanks ;)
The size is not a factor afaik but the background is. Either add a timer event that forces an erase:
Event Timer
GuiCls
Or load a non-transparent background GIF first:
Event Paint
GuiImage "Tweetie.gif", fit ; not the best example, of course
GuiImage "cross.gif", fit
GuiEnd
P.S.: It's actually easier to just add GuiCls (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1309):
include \masm32\MasmBasic\Res\MbGui.asm ; part of MasmBasic (http://masm32.com/board/index.php?topic=94.0)
Event Paint
GuiCls ; needed only for images with transparent background
GuiImage "cross.gif", fit
GuiEndTested OK on Win7-64, Win10-64, and my XP VM.
Quote from: blue_devil on May 26, 2017, 10:33:17 PM
1. I also cannot managed to run on Win10x64. I am stuck like hutch--.
yes, sorry for that. I've run it on an VM with Win10x64 and it did work (free running and in a Debugger). I've currently no access to a real installation, so no change to track that bug for me. You might insert some INT3's and step though the program using OllyDbg to see were it goes wrong.
JJ could jump in with showing his implementation, but he is unfortunately more interested in making people using his library :(
Hello qWord,
How are you ?
:icon14:
qword,
I can sympathise to this extent that code that has worked for years from XP and earlier needed to be changed for both Win7 64 and more recently Win10 64 so with code that I regularly use I build it in Win10 64 then back test it on Win7 and XP. So far with 64 bit MASM I have only developed on Win10 64 but so far it has all worked on Win7 64 so I don't have any problems there.
Hello, here is my version. Works in W7 64bits. Nevertheless I have noticed that the memory asigned to it grows each time you resize the window, surely it is any create_something that needs destroy it. I left it to the good reader :bgrin:
Quote from: caballero on May 27, 2017, 06:37:58 AM
Hello, here is my version. Works in W7 64bits. Nevertheless I have noticed that the memory asigned to it grows each time you resize the window, surely it is any create_something that needs destroy it. I left it to the good reader :bgrin:
Caballero thank you. I have compiled sources on Win7x86 and Win10x64 with old ML.exe. And they both worked on x86 and x64 virtual machines.
@qWord, today i worked on your sources and debuged them a lot but i couldn't find the differences that jj mentioned earlier. I xored the esi but nothing changed. And i also tried old ML and new ML.exe from Visual Studio :/
I am now preparing sources, when finished i will publish here. 8) And then i will come with new topic new sources and new questions :icon_redface: :idea:
Quote from: caballero on May 27, 2017, 06:37:58 AMthe memory asigned to it grows each time you resize the window
To test it, use SetTimer to call InvalidateRect, i.e. to trigger WM_PAINT events. After a while, Task Manager should show a trend.
The screenshot below shows the behaviour of an enlarged cross.gif (reply #20) after 55 minutes of cpu time. Looks quite ok, especially when compared to Firefox. Noteworthy: The working set starts at around 4.x MB and then
increases steadily. This looks like a leak, but strangely enough, it stabilises after 10-20 minutes at 5.3 MB. I have no explanation for this behaviour. The page errors are also high in comparison to Firefox.
Your GDIPlusWM04.exe starts with a somewhat higher working set, but it remains remarkably stable when running - except when you resize the window, as you rightly noticed. What exactly do you do when the size changes?
@caballero
I want to ask some questions
1. You did define the path of the gif file by:
WSTR szAnimGif, "Gangster.gif"
So why did you used WSTR macro, instead of defining directly
2. I wrote "FileOpen" function. By this function user can open any gif file s/he wants. Not a single one. So i need to change "szAnimGif" variable under my "FileOpen" funtion before calling your "prLoadAnimGif" function. I used lstrcpy but it didnt worked:
invoke lstrcpy, addr szAnimGif, addr ofn.lpstrFile
invoke prLoadAnimGif
Any ideas?
Thanks.
1+2: Gdi+ needs the Unicode versions! Put an int 3 before the lstrcpy and launch Olly. Unless you are explicitly using the "W" version, i.e. GetOpenFileNameW, you have Ansi there.
Olly,this software seems not to download.
Don't you sleep? :biggrin:
>use SetTimer to call InvalidateRect
I do it in this way
>What exactly do you do when the size changes?
It is in the code. With regarding to gdi+:
* I create a gdi+bitmap
* I create a gdi+double_buffer
Previously I delete both, otherwise the size of the program will increase without stop. Unfortunately, its size grows even if you reduce the size of the screen. I imagine it must create something internally that we are not destroying previously.
Another possibility is to make it in gdi (not +). One day, when I have time.
Edited: Now you can choose another gif file pressing the "1" button.
Is there no way to change the attached zip file when editing the post? ::)
Well, a fixed version for an small issue on the string filter for opening a file.
Quote from: newrobert on May 27, 2017, 06:02:25 PM
Olly,this software seems not to download.
Just tested, it works: direct link to zip file (http://www.ollydbg.de/odbg201.zip).
Quote from: caballero on May 27, 2017, 08:07:05 PM
Is there no way to change the attached zip file when editing the post? ::)
Shouldn't be a problem. Just uncheck the current attachment, then add a new one. It is a good idea to use a new name for the new attachment, as either browsers or the SMF software may give users the old cached one if you use the same name again.
Re leaks, here is what I get with some diagnostic code added:
** line 195, GdipGraphicsClear InvalidParameter
** line 196, GdipDrawImageRectI InvalidParameter
** line 202, GdipDrawImagePointRectI InvalidParameter
** line 301, GdipDeleteGraphics ObjectBusy
...
** line 301, GdipDeleteGraphics ObjectBusy
** line 272, GdipFree GenericError
The line 301 error appears every time when you resize the window. And as soon as you put the correct call there, all is fine with the working set, no more leak ;)
Apologies that this requires MasmBasic :bgrin:
Open the *.asc in RichMasm and hit F6. Press Ctrl G to insert the line number. I have changed only
- a handful of lines on top,
- gsi->Gsi because of a name conflict,
- invoke Gdi** -> invGdip Gdi**
No, I'm not able to change the f**cking file. Well, it is good to read the docs :lol: better use "GdipDisposeImage" for delete the gdi+ bitmap than "GdipDeleteGraphics" :greenclp:
Well, here it is the new working version. Now the mem size decreases when the window is aminorated. Nevertheless I have noticed that it size increases with no reason when the gif is changed. :icon_rolleyes:
Quote from: caballero on May 27, 2017, 10:21:48 PM
Well, it is good to read the docs :lol: better use "GdipDisposeImage"
Yes, RTFM is always a good idea. But it's much easier if you know that the culprit is GdipDeleteGraphics in line 301 :P
You still have 3*InvalidParameter to solve, but these calls are apparently not necessary.
> I have noticed that it size increases with no reason when the gif is changed.
For that, it is convenient to erase the objects before loading the new gif, as we have done in the resize section. With that it gets quite accurate. I left it to the good reader :t
Hello. A revision of the animated gif viewer with gdi+. This enhanced version work well with all the compilers: fasm, masm, nasmx, PellesC and TinyC for win32 and win64. Now transparent gifs do not blur the background. Besides now you can open any other gif than the default one, bearing in mind that need to use unicode chars for that.
It works fine now, but I see big differences between your display and mine. Is it the smoothing?
Attached an example - drag the tweety over ImageInfo.exe to see my version, press "0" in GDIPlusWM01.exe to open the GIF.
P.S.: Another odd thing is that the gangster appears far too small on launch, i.e. I have to resize the window to see it properly. In contrast, the tweety appears with the correct size.
I only get the error "Error leyendo gif" twice
Even if you extract all three files to the same folder and launch the exe from there?
Oops, I forgot that it expects gangster.gif there, too; this is your original code with the hard-coded path.
- re size of Gangster: you get the correct values, but Windows imposes a minimum width for the main window (your code is OK)
- I got an "unknown error" for the two GdipAlloc calls, but your code is OK: MSDN is wrong (https://msdn.microsoft.com/en-us/library/windows/desktop/ms534045(v=vs.85).aspx), GdipAlloc does not return a GpStatus but rather a pointer.
I execute yours and it seems to works fine
Well, there's some blur at the the right and bottom borders that dissapears after a while. Do you mean this? How did you do the double buffer and cleaning it?
Quote from: caballero on May 29, 2017, 02:28:34 AMWell, there's some blur at the the right and bottom borders that dissapears after a while.
Yes, but that's a different phenomenon. The blur comes from using \Masm32\MasmBasic\Res\MbBackground.gif as a background image, i.e. for "cleaning"; this is a 1 pixel image, and apparently when stretching to full size, Gdi+ plays little smoothing games :(
The outcome looks different with a "bigger" background, like the attached beach.jpg; unfortunately, this makes also come out the little defects in the tweety gif. Pretty odd behaviour.
Another solution is a GuiCls in the paint handler (which just paints the default main window background). See the difference in attachment. Note all three exes check the folder for all kind of images, you can scroll through them with the left and right keys (and rotate them with R and L, but that's irrelevant here).
I create a double buffering in memGraphics and clean it with GdipGraphicsClear.
GdipGraphicsClear sounds like a good idea. May I steal it from you? ;)
It's not my property :P
Hello;
I have edit the sources caballero had shared. Bu i am stuck again. Ok here are the issues:
1. I have add a "Close" menu item. I want to close the working Gif and want to see a blank window. I have tried several of thse commands but neither of them worked:
.elseif eax == IDM_FILE_CLOSE
;invoke KillTimer, [hWnd], cdIdTimer
;invoke GdipDisposeImage, [hGraphics]
;invoke GdipFree, [pPropertyItem]
;invoke GdipDeleteGraphics, [memGraphics]
;invoke GdipDeleteGraphics, [hGraphics]
;invoke UpdateWindow,hWin
2. I have added a "Open" menu item and also an accelerator for it. But it only works for one time like yours caballero. When i click open again -i mean call "FileOpen" again- OpenFile dialog doesn't recognize the gif file. I debugged it. So the problem is when i call ofn OpenFilename Structure the PATH of the secondly opened file overwrites the szFilter variable. Unfortunately i couldn't managed to fixed this issue.
FileOpen Proc Uses EBX
;LOCAL ofn :OPENFILENAME
Invoke RtlZeroMemory,addr ofn,SizeOf ofn
mov ofn.lStructSize, sizeof OPENFILENAME
m2m ofn.hwndOwner, hWnd
m2m ofn.hInstance, hInstance
m2m ofn.lpstrFilter, offset szOfnFilter ;Our Unicode filter
;mov ofn.lpstrCustomFilter,
;mov ofn.nMaxCustFilter,
;mov ofn.nFilterIndex,
;lea eax, szFileName
mov ofn.lpstrFile, offset szAnimGif ;Our Unicode file path
mov ofn.nMaxFile, sizeof szAnimGif * 2;trying to alloc a big part
;mov ofn.lpstrFileTitle
;mov ofn.nMaxFileTitle
;invoke GetModuleFileName,NULL,offset szBuffer,MAX_PATH
;mov ofn.lpstrInitialDir,offset SzBuffer
mov ofn.lpstrTitle, offset szOpenGif ;Dosya aç diyaloğonun başlığı
mov ofn.Flags, OFN_EXPLORER OR OFN_FILEMUSTEXIST OR OFN_HIDEREADONLY OR OFN_PATHMUSTEXIST OR OFN_LONGNAMES
;mov ofn.nFileOffset
;mov ofn.nFileExtension
mov ofn.lpstrDefExt, NULL
invoke GetOpenFileNameW,addr ofn ;Show Open File Diolog
.if eax
;Close old File?
invoke GdipDeleteGraphics, [memGraphics]
invoke GdipDisposeImage, [hGraphics]
;Load GIF
invoke prLoadAnimGif
invoke prGetGifSize
invoke SetMainWindowSize
mov dword ptr [nFramePosition], 0
invoke BeginPaint, [hWnd], offset ps
invoke prDrawFrameGif, eax
invoke EndPaint,[hWnd], offset ps
.EndIf
;invoke lstrcpyW,ofn.lpstrFile, chr$("hataoruBlueDevil.gif") ; itried interesting things but neigter of them worked
;m2m ofn.lpstrFilter, offset szOfnFilter
RET
FileOpen EndP
3. I also checked the macros asm because i want see that WSTR does. caballero you define a szAnimGif widestring like "blahblaf.GIF". It works first time. But when we try to open something new, szAnimGif turns like "C:\dir\anotherDir\maybeOneMoreDir\andFancy.Gif". At the end this variable overwrites our filter variable.
4. I also discovered one more thing. I execute proggy on a flash usb. like F:\proggy.exe and no errors. because the path is small it didn't overwrite the filter.
5.Because szFilter is overwritten, we cant select them on the openfile dialog. But we can write the name of the gif file to the name edit. And when we enter it we can show our gif on our dialog
Thank you for everything
No time to look in detail, but just one question: How does OPENFILENAME (Ansi) work together with GetOpenFileNameW?
You are right as ever, JJ, nevertheless, I don't see any difference between them
OPENFILENAMEW STRUCT
lStructSize DWORD ?
hwndOwner DWORD ?
hInstance DWORD ?
lpstrFilter DWORD ?
lpstrCustomFilter DWORD ?
nMaxCustFilter DWORD ?
nFilterIndex DWORD ?
lpstrFile DWORD ?
nMaxFile DWORD ?
lpstrFileTitle DWORD ?
nMaxFileTitle DWORD ?
lpstrInitialDir DWORD ?
lpstrTitle DWORD ?
Flags DWORD ?
nFileOffset WORD ?
nFileExtension WORD ?
lpstrDefExt DWORD ?
lCustData DWORD ?
lpfnHook DWORD ?
lpTemplateName DWORD ?
OPENFILENAMEW ENDS
OPENFILENAMEA STRUCT
lStructSize DWORD ?
hwndOwner DWORD ?
hInstance DWORD ?
lpstrFilter DWORD ?
lpstrCustomFilter DWORD ?
nMaxCustFilter DWORD ?
nFilterIndex DWORD ?
lpstrFile DWORD ?
nMaxFile DWORD ?
lpstrFileTitle DWORD ?
nMaxFileTitle DWORD ?
lpstrInitialDir DWORD ?
lpstrTitle DWORD ?
Flags DWORD ?
nFileOffset WORD ?
nFileExtension WORD ?
lpstrDefExt DWORD ?
lCustData DWORD ?
lpfnHook DWORD ?
lpTemplateName DWORD ?
OPENFILENAMEA ENDS
> BlueDevil
1. Which OS are you using?
2. Do you have the latest version?
3. Neither of nasmx, fasm, masm, tinyc or pellesc works to you? All of them works to me in my W7-64 and WXP-32
I experimented the same issue in one of the first versions, that's why I allocated szAnimGif at the end of the data. You can try to change
mov ofn.nMaxFile,MAXSIZE ; Indicamos el tamaño máximo del fichero
by:
mov ofn.nMaxFile,MAXSIZE/2 ; Indicamos el tamaño máximo del fichero
By some reason fullfil the buffer with stuff though it does not come to mind
Try to value MAXSIZE equ 600 (instead 300, for example)
Quote from: caballero on May 31, 2017, 04:35:35 AM
You are right as ever, JJ, nevertheless, I don't see any difference between them
You are right indeed - they are identical. I thought there was some fixed size buffer inside it, wrong idea :icon_redface:
P.S.: I have tried for an hour now to chase the GetOpenFileNameW bug, no luck. All I can say is that there is heap corruption - but no heap involved there ::)
Attached a version that works. There is still a problem with the heap, but at least you
may understand why FileOpen crashed.