News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

A little fire using GDI+

Started by Phoenix, December 24, 2004, 11:12:01 PM

Previous topic - Next topic

Phoenix

Quote from: pbrennick on December 25, 2004, 05:15:30 AM
The attached zipfile has been reworked so it assembles without error ...


Hi all,

I should have mentioned that i did this code using WinAsm Studio, as the paths are declared in general there i did forget to do this for the posting.Sorry!

Does someone have ideas to optimize the code? I also have a little problem with the settimer_api, seems that windows accepts only steps of 10 ms, so if you set uElapse to 25, the timerproc is called every 30ms.

Phoenix

MichaelW

#16
I don't know much about it, but I think you are supposed to use the multimedia timers for tasks that require a high timing accuracy.

MSDN: Multimedia Timers

The functions seem to be easy to use, and everything I tested other than timeBeginPeriod (and timeEndPeriod) seemed to work just as I expected. On the one system I tested the timeGetDevCaps function returned minimum and maximum periods of 1 and 1000000ms.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    .486                       ; create 32 bit code
    .model flat, stdcall       ; 32 bit memory model
    option casemap :none       ; case sensitive

    include \masm32\include\windows.inc
    include \masm32\include\masm32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc

    include \masm32\include\winmm.inc

    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib

    includelib \masm32\lib\winmm.lib

    include \masm32\macros\macros.asm

    TimeProc PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD

    printv MACRO varname:VARARG
      FOR arg, <varname>
        invoke StdOut, reparg(arg)
      ENDM
    ENDM

    NL  EQU SADD(13,10)

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data     
      tcaps   TIMECAPS <>
      timerID dd 0
      count   dd 0
      buffer  db 30 dup(0)
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    invoke timeGetDevCaps, ADDR tcaps, SIZEOF tcaps
    cmp   eax, TIMERR_NOERROR
    je    @F
    printv chr$("timeGetDevCaps returned an error"), NL
  @@:       
    printv chr$("wPeriodMin = "), ustr$(tcaps.wPeriodMin), chr$("ms"), NL
    printv chr$("wPeriodMax = "), ustr$(tcaps.wPeriodMax), chr$("ms"), NL

    ; This does not seem to produce any significant effect.
    ;invoke timeBeginPeriod, 100
    ;cmp   eax, TIMERR_NOERROR
    ;je    @F
    ;printv chr$("timeBeginPeriod returned an error"), NL
  @@:   

    printv chr$("Timing 10000 timer events...")

    ; Sync with timer tick for better accuracy.
    call  GetTickCount
    mov   ebx, eax
  @@:
    call  GetTickCount   
    cmp   ebx, eax
    je    @B

    call  GetTickCount
    push  eax   
    invoke timeSetEvent, 1, 1, offset TimeProc, 0, TIME_PERIODIC   
    mov   timerID, eax
    test  eax, eax
    jnz   @F
    printv chr$("timeSetEvent returned an error"), NL   
  @@:
    cmp   count, 10000
    jb    @B

    invoke timeKillEvent, timerID
    cmp   eax, TIMERR_NOERROR
    je    @F
    printv chr$("timeKillEvent returned an error"), NL
  @@:

    ;invoke timeEndPeriod, 100
    ;cmp   eax, TIMERR_NOERROR
    ;je    @F
    ;printv chr$("timeEndPeriod returned an error"), NL
  @@:

    call  GetTickCount
    pop   ebx
    sub   eax, ebx

    printv NL, chr$("Elapsed time = "), ustr$(eax), chr$("ms"), NL

    printv NL, chr$("Press enter to exit..."), NL
    invoke StdIn, addr buffer, 1
    exit

TimeProc proc uID:DWORD, uMsg:DWORD, dwUser:DWORD, dw1:DWORD, dw2:DWORD
    inc count
    ret   
TimeProc endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


[edit]Fixed a stupid mistake in the timer sync code[/edit]

eschew obfuscation

MichaelW

Quote from: pbrennickI would encourage you to place the dll in the c:\windows\system directory so you can use it for all your GDI+ needs.

Redist.txt that accompanies the Microsoft download:
Quote
===========
Gdiplus.dll
===========

For Windows XP use the system-supplied gdiplus.dll.  Do not install a new gdiplus.dll over the system-supplied version (it will fail due to Windows File Protection). 

For Windows 2000, Windows Millennium Edition, Windows NT 4.0 and Windows 98, install gdiplus.dll into the private directory of the application not into the system directory.

In addition to the rights granted in Section 1 of the Agreement ("Agreement"), with respect to gdiplus.dll for Windows 2000, Windows Millennium Edition, Windows NT 4.0 and Windows 98, you have the following non-exclusive, royalty free rights subject to the Distribution Requirements detailed in Section 1 of the Agreement:

(1) You may distribute gdiplus.dll solely for use with Windows 2000, Windows Millennium Edition, Windows NT 4.0 and Windows 98.

eschew obfuscation

pbrennick

We are talking about installing it in win98, here, where there is NO possible collision with a previous version as it never was released with this windows version.
Paul

MichaelW

GDI+ was not released with Windows 2000, NT4, or ME, but that specific warning includes those versions.

QuoteGDI+ can be used in all Windows-based applications. GDI+ is new technology that is included in Windows XP and the Windows Server 2003. It is required as a redistributable for applications that run on the Microsoft Windows NT 4.0 SP6, Windows 2000, Windows 98, and Windows Millennium Edition (Windows Me) operating systems.

Perhaps this is a case of the right hand not knowing what the left hand is doing, but Microsoft could have had a good reason for the warning, and I suspect that security might be part of it.


eschew obfuscation

Phoenix

MichaelW: Thankyou for your suggestion to use mmTimer, i am working on this.

Quote from: MichaelW on December 25, 2004, 05:00:26 PM
GDI+ was not released with Windows 2000, NT4, or ME, but that specific warning includes those versions.

....but Microsoft could have had a good reason for the warning, and I suspect that security might be part of it.


What should happen if using gdiplus.dll? This is part of XP, and MS states that it works with 98, Me, W2k and so on. I use gdiplus on a W2K-system, and it is installed in the system32-directory. So what is the difference, if we put it to the application-directory or to the system32-directory?

As far as i know, the security problem is in the JPEG Parsing Engine (Buffer Overflow) so this might be the problem with it.

For anything else, i noticed that gdi+ is very powerful, it is sometimes unbelievable what is possible. And we can use it from every HLL or with asm using flat API calls with great results.

MichaelW

QuoteSo what is the difference, if we put it to the application-directory or to the system32-directory?

I think I found the likely explanation here:
Quote
Although the updated GDIPlus.dll is designed to be compatible with previous versions, there are always applications that are too tightly designed to the idiosyncrasies of a given version. The result can be a situation not anticipated by you or the application developer. So we encourage you to work in concert with your software vendor for an update that has been tested with the latest version of GDI+.

Basically, it seems that Microsoft wants to avoid a situation where the updated GDIPlus.dll breaks existing applications. For Windows 98 SE and 2000 there is a relatively simple method of forcing an existing application to use a local copy of the DLL -- see Private DLLs, The second side-by-side approach... here. So I now think it would be reasonable to put the DLL in the system/system32 directory, and then force any application that breaks to use the local copy.
eschew obfuscation

Phoenix

Quote from: MichaelW on December 26, 2004, 09:45:52 AM

Basically, it seems that Microsoft wants to avoid a situation where the updated GDIPlus.dll breaks existing applications.


MichaelW: Thank you for your explanations (and patience), i think they made me a little bit more careful. But, however, i think the technology behind gdiplus is one for the future, and the up to date version of this dll can be used without doubt, either in system32- or application-directory. The reason for me to put it into the system32-directory on my system is that - with all versions of my vb and asm-projects - I had it a lot of times on my harddrive. But i will do a further version-check in future!