Windows - Kommandozeilenparameter unter Windows NT-Versionen



  • Bei meinem Programm wird nur unter Windows98 und ME korrekt eine Datei geöffnet wenn sie direkt mit dem Programm geöffnet werden soll (Kommandozeilenparameter übergeben). Bei 2000 und XP gibt es die Fehlermeldung aus (wenn mciSendString FALSE zurückgibt); die NT-Versionen geben ja in einem ersten Parameter den Programmnamen aus? Jedenfalls wenn das "i" angeklickt wird steht dort doch der korrekte Dateiname!
    Was muss ich an dem Code ändern? Unter Win98/ME sollte es dennoch auch laufen.
    Das Programm wurde mit MASM32 erstellt und Prostart, daher sind einige Routinen ausgelagert.

    Vielen Dank!

    .486                      ; create 32 bit code
          .model flat, stdcall      ; 32 bit memory model
          option casemap :none      ; case sensitive
    
          include mp3Player.inc        ; local includes for this file
          include dbmacros.asm
          include errormac.asm
          include \masm32\include\winmm.inc
    includelib \masm32\lib\winmm.lib
    
    includelib \masm32\lib\shlwapi.lib
    include \masm32\include\shlwapi.inc
    
    .data
    
    ButtonText1 db ">>",0
    ButtonText2 db "<<",0
    ButtonText3 db "Stop",0
    ButtonText4 db "<<<",0
    ButtonClassName db "button",0
    ButtonClassName2 db "button",0
    ButtonClassName3 db "button",0
    ButtonClassName4 db "button",0
    
    TrackBarClassName db "msctls_trackbar32",0
    
    sspielzeit db "Spielzeit:",0
    smin db "min.",0
    
    open1 db "open ", 1024 dup(?),0
    open2 db " type MPEGVideo alias MyAlias",0        
    play db "play MyAlias",0
    stop db "stop MyAlias",0
    filename db 1024 dup(?)
    close db "close MyAlias",0
    vol100 db "setaudio MyAlias volume to 1000",0
    vol90 db "setaudio MyAlias volume to 900",0
    vol80 db "setaudio MyAlias volume to 800",0
    vol70 db "setaudio MyAlias volume to 700",0
    vol60 db "setaudio MyAlias volume to 600",0
    vol50 db "setaudio MyAlias volume to 500",0
    vol40 db "setaudio MyAlias volume to 400",0
    vol30 db "setaudio MyAlias volume to 300",0
    vol20 db "setaudio MyAlias volume to 200",0
    vol10 db "setaudio MyAlias volume to 100",0
    vol0 db "setaudio MyAlias volume to 0",0
    
    status db "status MyAlias length",0
    sBuffer db 255 DUP(?),0
    zeitstr db 255 dup (?),0
    basis dd 1000
    minuten dd 60
    sformat db "%i",0
    spos db 255 dup (?),0
    cpos db "status MyAlias position ",0
    forward db " play MyAlias from "
    sforward db 255 dup(?),0
    lautst db "Lautst.",0
    
    tensec dd 10000
    sec dd 1000
    tbnull db 0
    tbhundert dd 100
    tbsiebzig dd 70
    svol db 255 dup (?),0
    
    mci3 db 0
    
    fehler db "Fehler bein Öffnen der Datei/keine kompatible Mediendatei oder von dieser Windows-Version nicht unterstützt",0
    
    .data?
    hwndButton HWND ?
    hwndTrack HWND ?
    zahl dd ?
    laenge dd ?
    zahlpos dd ?
    devicecontext dd ?
    printcurpos dd ?
    strlength dd ?
    
    ivol dd ?
    
    .const
    ButtonID equ 1
    ButtonID2 equ 2
    ButtonID3 equ 3
    ButtonID4 equ 4
    TrackBarID equ 5
    
    .code
    
    ; #########################################################################
    
    start:
    
          invoke InitCommonControls
    
        ; ------------------
        ; set global values
        ; ------------------
          invoke GetModuleHandle, NULL
          mov hInstance, eax
    
          invoke GetCommandLine
          mov CommandLine, eax
    
          invoke LoadIcon,hInstance,500    ; icon ID
          mov hIcon, eax
    
          invoke LoadCursor,NULL,IDC_ARROW
          mov hCursor, eax
    
          invoke GetSystemMetrics,SM_CXSCREEN
          mov sWid, eax
    
          invoke GetSystemMetrics,SM_CYSCREEN
          mov sHgt, eax
    
          call Main
    
          invoke ExitProcess,eax
    
    ; #########################################################################
    
    Main proc
    
        LOCAL Wwd:DWORD,Wht:DWORD,Wtx:DWORD,Wty:DWORD
    
        STRING szClassName,"Prostart_Class"
    
        SingleInstanceOnly ADDR szClassName
    
      ; --------------------------------------------
      ; register class name for CreateWindowEx call
      ; --------------------------------------------
        invoke RegisterWinClass,ADDR WndProc,ADDR szClassName,
                           hIcon,hCursor,COLOR_BTNFACE+1
    
        mov Wwd, 300
        mov Wht, 200
        invoke TopXY,Wwd,sWid
        mov Wtx, eax
        invoke TopXY,Wht,sHgt
        mov Wty, eax
    
        invoke CreateWindowEx,WS_EX_LEFT or WS_EX_ACCEPTFILES,
                              ADDR szClassName,
                              ADDR szDisplayName,
                              WS_OVERLAPPED or WS_SYSMENU,
                              Wtx,Wty,Wwd,Wht,
                              NULL,NULL,
                              hInstance,NULL
        mov hWnd,eax
    
      ; ---------------------------
      ; macros for unchanging code
      ; ---------------------------
        DisplayMenu hWnd,600
        DisplayWindow hWnd,SW_SHOWNORMAL
    
        call MsgLoop
        ret
    
    Main endp
    
    ; #########################################################################
    
    RegisterWinClass proc lpWndProc:DWORD, lpClassName:DWORD,
                          Icon:DWORD, Cursor:DWORD, bColor:DWORD
    
        LOCAL wc:WNDCLASSEX
    
        mov wc.cbSize,         sizeof WNDCLASSEX
        mov wc.style,          CS_BYTEALIGNCLIENT or \
                               CS_BYTEALIGNWINDOW
        m2m wc.lpfnWndProc,    lpWndProc
        mov wc.cbClsExtra,     NULL
        mov wc.cbWndExtra,     NULL
        m2m wc.hInstance,      hInstance
        m2m wc.hbrBackground,  bColor
        mov wc.lpszMenuName,   NULL
        m2m wc.lpszClassName,  lpClassName
        m2m wc.hIcon,          Icon
        m2m wc.hCursor,        Cursor
        m2m wc.hIconSm,        Icon
    
        invoke RegisterClassEx, ADDR wc
    
        ret
    
    RegisterWinClass endp
    
    ; ########################################################################
    
    MsgLoop proc
    
      ; ------------------------------------------
      ; The following 4 equates are available for
      ; processing messages directly in the loop.
      ; m_hWnd - m_Msg - m_wParam - m_lParam
      ; ------------------------------------------
    
        LOCAL msg:MSG
    
        StartLoop:
          invoke GetMessage,ADDR msg,NULL,0,0
          cmp eax, 0
          je ExitLoop
          invoke TranslateMessage, ADDR msg
          invoke DispatchMessage,  ADDR msg
          jmp StartLoop
        ExitLoop:
    
        mov eax, msg.wParam
        ret
    
    MsgLoop endp
    
    ; #########################################################################
    
    WndProc proc hWin   :DWORD,
                 uMsg   :DWORD,
                 wParam :DWORD,
                 lParam :DWORD
    
        LOCAL var    :DWORD
        LOCAL caW    :DWORD
        LOCAL caH    :DWORD
        LOCAL Rct    :RECT
        LOCAL buffer1[128]:BYTE  ; these are two spare buffers
        LOCAL buffer2[128]:BYTE  ; for text manipulation etc..
        LOCAL szDropFileName[260]:BYTE
    
        .if uMsg == WM_COMMAND
        ;======== toolbar commands ========
            .if wParam == 50
                jmp b1
    
            .elseif wParam == 51
                invoke mciSendString, ADDR play, ADDR mci3,0,0
            .elseif wParam == 52
                invoke mciSendString, ADDR stop, ADDR mci3,0,0
    
            .elseif wParam == 53
                lea eax, szFileName
                invoke MessageBox,hWin,eax,
                                  ADDR szDisplayName,MB_OK
    
    ;------------
    
    .elseif wParam==ButtonID
    invoke InvalidateRect, hWin, NULL, TRUE
    call curpos
    call goforward
    
    .elseif wParam==ButtonID2
    invoke InvalidateRect, hWin, NULL, TRUE
    call curpos
    call goback
    
    ;------------
    
    .elseif wParam==ButtonID3
    
    invoke mciSendString, ADDR stop, ADDR mci3,0,0
    invoke mciSendString, ADDR close, ADDR mci3,0,0
    invoke KillTimer, hWin, 1
    
    .elseif wParam==ButtonID4
    invoke mciSendString, ADDR stop, ADDR mci3,0,0
    invoke mciSendString, ADDR close, ADDR mci3,0,0
    invoke InvalidateRect, hWin, NULL, TRUE
    jmp abspielen
            .endif
    
        ;======== menu commands ========
    
            .if wParam == 1001
    
       b1: invoke mciSendString, ADDR stop, ADDR mci3,0,0
        invoke mciSendString, ADDR close, ADDR mci3,0,0
    
              ; --------------------------------------
              ; szFileName is defined in Filedlgs.asm
              ; --------------------------------------
                mov szFileName[0],0     ; set 1st byte to zero
                invoke GetFileName,hWin,SADD("Open A File"),
                                        SADD("mp3 Audioformat",0,"*.mp3",0,"wma Audioformat",0,"*.wma",0,"PCM/wave-Audio .wav",0,"*.wav",0,"MIDI-Dateien .mid",0,"*.mid",0, "MPG-Filme",0,"*.mpg",0,"AVI-Filme",0,"*.avi",0,"alle Dateien",0,"*.*",0) ; 
                cmp szFileName[0],0     ; zero if cancel pressed in dlgbox
                je @F
    
    abspielen:  
                mov open1[5],0       ;open ,0 und nicht weiter, string leeren
                invoke GetShortPathName, ADDR szFileName, ADDR filename, 255
    
    Start: invoke InvalidateRect, hWin, NULL, TRUE
    
      lea esi, open1 
     FindLastByte: 
      lodsb 
      Or al, al 
      jnz FindLastByte 
    
      dec esi 
      mov edi, esi 
      lea esi, filename
      CatStrings: 
      lodsb 
      Or al, al 
      jz Done 
      stosb 
      jmp CatStrings 
    
     Done: 
      mov al, 0
      stosb 
    
                     ;Start:   
      lea esi, open1
     FindLastByte2: 
      lodsb 
      Or al, al 
      jnz FindLastByte2 
    
      dec esi 
      mov edi, esi 
      lea esi, open2
      CatStrings2: 
      lodsb 
      Or al, al 
      jz Done2 
      stosb 
      jmp CatStrings2 
    
     Done2: 
      mov al, 0
      stosb 
    
                lea eax, open1
    
                invoke mciSendString, eax, ADDR mci3,0,0
    
                    lea ebx, mci3
                    lea eax, play
                    invoke mciSendString, eax, ebx,0,0
                    cmp eax, 0
    
                    je ok
                    invoke MessageBox,hWin,ADDR fehler,ADDR szDisplayName,MB_OK or MB_ICONERROR
    
                   ok: invoke SetTimer, hWin, 1,sec, 0
                   call getlength
    
                @@:
    .elseif wParam == 1002
              ; --------------------------------------
              ; szFileName is defined in Filedlgs.asm
              ; --------------------------------------
                mov szFileName[0],0     ; set 1st byte to zero
                invoke SaveFileName,hWin,SADD("Save File As ..."),
                                         SADD("All files",0,"*.*",0,0)
                cmp szFileName[0],0     ; zero if cancel pressed in dlgbox
                je @F
              ; ---------------------------------
              ; perform your file save code here
              ; ---------------------------------
                invoke MessageBox,hWin,ADDR fehler,ADDR szDisplayName,MB_OK
                @@:
    
            .endif
    
            .if wParam == 1010
                invoke SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL
    
            .elseif wParam == 1900
                ShellAboutBox hWin,hIcon,\
                    "About nativeConny#Windows Application",\
                    "nativeConny Medienplayer",13,10,"Copyright © C. M. Obrecht, 2007", 13,10,13,10,"100% native opcodes /win32API, 100% Assembler pure and symply (-:"
            .endif
    ;====== end menu commands ======
    
        .elseif uMsg == WM_DROPFILES
            invoke DragQueryFile,wParam,0,ADDR szFileName,sizeof szFileName  ; war szDropFileName
          invoke mciSendString, ADDR stop, ADDR mci3,0,0
        invoke mciSendString, ADDR close, ADDR mci3,0,0
    
            jmp abspielen
    
    ;------------trackbar messages--------------
    .elseif uMsg==WM_HSCROLL                      
    
    invoke SendMessage, hwndTrack, TBM_GETPOS, TRUE, NULL
    
    cmp eax, 100
    je v100
    cmp eax, 91
    je v90
    cmp eax, 80
    je v80
    cmp eax, 81
    je v80
    cmp eax, 82
    je v80
    cmp eax, 71
    je v70
    cmp eax, 69
    je v70
    cmp eax, 72
    je v70
    cmp eax, 60
    je v60
    cmp eax, 59
    je v60
    cmp eax, 58
    je v60
    cmp eax, 52
    je v50
    cmp eax, 54
    je v50
    cmp eax, 40
    je v40
    cmp eax, 30
    je v30
    cmp eax, 31
    je v30
    cmp eax, 32
    je v30
    cmp eax, 20
    je v20
    cmp eax, 10
    je v10
    cmp eax, 0
    je v0
    jmp vkein
    v100: invoke mciSendString, addr vol100, 0, 0, 0
    jmp vkein
    v90: invoke mciSendString, addr vol90, 0, 0, 0
    jmp vkein
    v80: invoke mciSendString, addr vol80, 0, 0, 0
    jmp vkein
    v70: invoke mciSendString, addr vol70, 0, 0, 0
    jmp vkein
    v60: invoke mciSendString, addr vol60, 0, 0, 0
    jmp vkein
    v50: invoke mciSendString, addr vol50, 0, 0, 0
    jmp vkein
    v40: invoke mciSendString, addr vol40, 0, 0, 0
    jmp vkein
    v30: invoke mciSendString, addr vol30, 0, 0, 0
    jmp vkein
    v20: invoke mciSendString, addr vol20, 0, 0, 0
    jmp vkein
    v10: invoke mciSendString, addr vol10, 0, 0, 0
    jmp vkein
    v0: invoke mciSendString, addr vol0, 0, 0, 0
    vkein: nop
    
    ;---------------/trackbar messages-----------
    
        .elseif uMsg == WM_CREATE
                invoke Do_ToolBar,hWin
    
    ;-----------------------------------------------
    
    invoke CreateWindowEx,NULL, ADDR ButtonClassName,ADDR ButtonText1,\
                            WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
                            250,120,30,20,hWin,ButtonID,hInstance,NULL
    		mov  hwndButton,eax
    
    invoke CreateWindowEx,NULL, ADDR ButtonClassName2,ADDR ButtonText2,\
                            WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
                            8,120,30,20,hWin,ButtonID2,hInstance,NULL
    		mov  hwndButton,eax
    
    invoke CreateWindowEx,NULL, ADDR ButtonClassName3,ADDR ButtonText3,\
                            WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON,\
                            8,30,32,20,hWin,ButtonID3,hInstance,NULL
    		mov  hwndButton,eax
    
    invoke CreateWindowEx,NULL, ADDR ButtonClassName4,ADDR ButtonText4,\
                            WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\
                            47,120,30,20,hWin,ButtonID4,hInstance,NULL
    		mov  hwndButton,eax
    
    ;------------------------trackbar-----------------------
    
    invoke CreateWindowEx,NULL,addr TrackBarClassName, NULL, WS_CHILD or WS_VISIBLE,220,60,70,20,hWin, TrackBarID, hInstance, NULL
    mov hwndTrack, eax
    invoke SendMessage, hwndTrack, TBM_SETRANGE, tbnull, tbhundert
    invoke SendMessage, hwndTrack, TBM_SETPOS, TRUE, tbsiebzig
    
    ;-------------------------------------------------------
    
    invoke GetCL,1, ADDR szFileName
    cmp szFileName, 0
    je nocmd
    jmp abspielen
    nocmd:
        .elseif uMsg == WM_SYSCOLORCHANGE
            invoke Do_ToolBar,hWin
    
        .elseif uMsg == WM_SIZE
            invoke SendMessage,hToolBar,TB_AUTOSIZE,0,0
    
        .elseif uMsg == WM_PAINT
            invoke Paint_Proc,hWin
    
            return 0
    
        .elseif uMsg == WM_CLOSE
    
        .elseif uMsg == WM_DESTROY
        invoke mciSendString, ADDR stop, ADDR mci3,0,0
        invoke mciSendString, ADDR close, ADDR mci3,0,0
        invoke KillTimer, hWin, 1
            invoke PostQuitMessage,NULL
            return 0
    
    .elseif uMsg==WM_TIMER
     .if wParam == 1
    
    call curpos
    mov zahlpos, eax
    fild zahlpos
    fidiv sec
    fistp zahlpos                                       
    invoke wsprintf, addr printcurpos, addr sformat, zahlpos
    mov strlength, eax
    invoke GetDC, hWin
    mov devicecontext, eax
    invoke TextOut,eax, 250, 100, addr printcurpos, strlength
    ;---------- length
    
                invoke TextOut,devicecontext, 90, 100, addr zeitstr, laenge
    
                invoke TextOut,devicecontext, 20, 100, addr sspielzeit, 10
    
                invoke TextOut,devicecontext, 120, 100, addr smin, 4
    
                invoke ReleaseDC, hWin, devicecontext
                                       ;--------- /length
    
    .endif
        .endif
    
        invoke DefWindowProc,hWin,uMsg,wParam,lParam
    
        ret
    
    WndProc endp
    
    ; ########################################################################
    
    TopXY proc wDim:DWORD, sDim:DWORD
    
        shr sDim, 1      ; divide screen dimension by 2
        shr wDim, 1      ; divide window dimension by 2
        mov eax, wDim    ; copy window dimension into eax
        sub sDim, eax    ; sub half win dimension from half screen dimension
    
        return sDim
    
    TopXY endp
    
    ; #########################################################################
    
    Paint_Proc proc hWin:DWORD
    
        LOCAL hDC      :DWORD
        LOCAL btn_hi   :DWORD
        LOCAL btn_lo   :DWORD
        LOCAL Rct      :RECT
        LOCAL Ps       :PAINTSTRUCT
    
        invoke BeginPaint,hWin,ADDR Ps
        mov hDC, eax
    
                invoke TextOut,hDC, 175, 62, addr lautst, 7
    
      ; ----------------------------------------
    
        invoke GetSysColor,COLOR_BTNHIGHLIGHT
        mov btn_hi, eax
    
        invoke GetSysColor,COLOR_BTNSHADOW
        mov btn_lo, eax
    
      ; ----------------------------------------
    
        invoke EndPaint,hWin,ADDR Ps
    
        ret
    
    Paint_Proc endp
    
    ; ########################################################################
    
    getlength proc
    
    invoke mciSendString, addr status, addr sBuffer,255, 0
    
    invoke StrToInt, addr sBuffer
    mov zahl, eax
    fild zahl
    fidiv basis
    fidiv minuten
    fist zahl
    invoke wsprintf, addr zeitstr, addr sformat, zahl 
    mov laenge, eax
    ret
    getlength endp
    
    curpos proc
    
    invoke mciSendString, addr cpos, addr spos, 255, 0
    invoke StrToInt, addr spos
    mov zahlpos, eax
    ret
    curpos endp
    
    goforward proc
    add eax, tensec
    invoke wsprintf, addr sforward, addr sformat, eax
    invoke mciSendString, addr forward, addr sforward,0,0
    ret
    goforward endp
    
    goback proc
    mov eax, zahlpos
    sub eax, tensec
    invoke wsprintf, addr sforward, addr sformat, eax
    invoke mciSendString, addr forward, addr sforward,0,0
    ret
    goback endp
    
    end start
    


  • Kenn mich mit ASM nicht aus, deshalb kann Dir nur ein Stichwort als Hilfestellung geben:
    Kann es sein, daß Du Unicode-Text unter WinNT/2k/XP bekommst statt ASCII unter Win98/Me? Und es deshalb Probleme gibt?

    Ein weiterer Stichwort: GetCommandLine()

    Martin



  • Ach ja Unicode, daran habe ich jetzt gar nicht gedacht...Danke. Habe ein ähnliches Programm zuerst mit VB5 geschrieben, dort funktioniert es auf allen Versionen problemlos (wenn ich wüsste die das dort gelöst wird 🙂 )



  • ...Unicode kann fast nicht sein, ist mir eingefallen; die MessageBox welche den Dateinamen der geöffneten Datei enthält zeigt ganz normal den Dateinamen, offensichtlich wird er schon übergeben (denke nicht dass ohne Unicode-Kompilierung automatisch die Unicode-Messagebox erscheinen kann?).
    Die exe ist hier zu finden: [url]http://rebenstudio-it.ch/downloads/nativeConnyASM.exe [/url]



  • Ist das ein GUI-Programm mit WinMain() oder ein Konsolen-Programm main()?

    Für WinMain() http://msdn2.microsoft.com/en-us/library/ms633559.aspx gibts den Übergabeparameter LPSTR lpCmdLine. Gemäß Doku ist das ganz eindeutig ANSI-Text und kein Unicode (hab mich also geirrt 😞 ).

    Da ich kein WinMain() in Deinem Source gefunden habe (sorry, bin kein ASM-Freak), muß ich davon ausgehen, daß Du main() mit den Übergabeparametern argc und argv verwenden müßtest.
    Andererseits finde ich diese Variablennamen auch nicht Ihrem Source 😕 Ist es so? Wenn ja, was liefern diese für Werte?

    Martin



  • Es ist ein GUI-Programm; in ASM gibt es keine WinMain-Funktion, die Parameter werden mit Funktionen (und einem Makro glaube ich, wie der funktioniert weiss ich nicht) geholt. Kannst ja die .exe runterladen.
    Komischerweise wird der Dateiname ja übergeben da er in der MessageBox steht, doch wieso wird er von der mciSendString oder GetShortPathName nicht richtig bearbeitet? Komisch



  • Nun habe ich getMciErrorString ausgewertet, in der MessageBox erscheint nun die Meldung der MCI. Beim Versuch eine Datei mit dem Programm zu öffnen erscheint nun "Fehler beim Öffnen von MCI" (und danach lässt sich auch keine Datei abspielen, erscheint immer "Gerät ist nicht geöffnet oder wird von MCI nicht erkannt). Nicht sehr aussagekräftige Mitteilung aber vieleicht hilft es etwas weiter?


Anmelden zum Antworten