News:

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

Main Menu

Error: line too long while using backslash

Started by bluedevil, September 14, 2022, 07:16:32 AM

Previous topic - Next topic

bluedevil

This line compiles without problem:

invoke  CreateWindowEx,WS_EX_CLIENTEDGE,addr ClassName,addr AppName,WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInst,NULL


But if cut this long line for the sake of readability, I got error A2039:line too long


invoke  CreateWindowEx, \
                WS_EX_CLIENTEDGE, \
                addr ClassName, \
                addr AppName, \
                WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE, \
                CW_USEDEFAULT, \
                CW_USEDEFAULT, \
                CW_USEDEFAULT, \
                CW_USEDEFAULT, \
                NULL, \
                NULL, \
                hInst, \
                NULL


But! If I only take fırst parameter near function name, again it compiles without problem:


invoke  CreateWindowEx,WS_EX_CLIENTEDGE, \
                addr ClassName, \
                addr AppName, \
                WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE, \
                CW_USEDEFAULT, \
                CW_USEDEFAULT, \
                CW_USEDEFAULT, \
                CW_USEDEFAULT, \
                NULL, \
                NULL, \
                hInst, \
                NULL


So, what is going on? And more importantly, what is the best assembly coding practice, in these kind of situations?

I removed the [Solved] as this forum is not a help desk. Our members help out where they can.
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
BlueDeviL Github

jj2007

a) Post the complete source, please, and specify which assembler version throws the error.
b) Never, ever use + to combine flags; your WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+... is a no no

zedd151

Try

invoke  CreateWindowEx, \
                WS_EX_CLIENTEDGE, \
                addr ClassName, \
                addr AppName, \
                WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_VISIBLE, \
                CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, \
                NULL, NULL,  hInst, NULL

Probably a limit how many "\" can be used
For window style, I usually put that in an equate and pass that...
wstyle equ WS_OVERLAPPED or WS_SYSMENU etc. for example
Then pass wstyle instead of the long string


jj2007


bluedevil

I am writing iczelions win32 tutorials samples in MASM64 SDK beta 2.


    OPTION DOTNAME                          ; required for macro files
    option casemap:none                     ; case sensitive

; _________________________________________________________________________
; MASM64 macros

    include \masm64\include64\win64.inc     ; main include file
    include \masm64\macros64\vasily.inc     ; main macro file
    include \masm64\macros64\macros64.inc   ; auxillary macro file

    STACKFRAME                              ; create a default stack frame

; _________________________________________________________________________
; include files

    include \masm64\include64\kernel32.inc
    include \masm64\include64\user32.inc
    include \masm64\include64\comctl32.inc

; _________________________________________________________________________
; libraries

    includelib \masm64\lib64\kernel32.lib
    includelib \masm64\lib64\user32.lib
    includelib \masm64\lib64\comctl32.lib

; _________________________________________________________________________
; funtion prototypes

    WndProc             PROTO   :HWND,:UINT,:WPARAM,:LPARAM

; _________________________________________________________________________
; constant variables

.const
    IDC_PROGRESS    equ 1
    IDC_STATUS     equ 2
    IDC_TIMER     equ 3
   
    PBM_SETRANGE        equ WM_USER+1
    PBM_SETPOS          equ WM_USER+2
    PBM_DELTAPOS        equ WM_USER+3
    PBM_SETSTEP         equ WM_USER+4
    PBM_STEPIT          equ WM_USER+5

; _________________________________________________________________________
; initialized variables

.data
    ClassName           db "CommonControlWin64Class", 0    ; the name of our window class
    AppName             db "x64 Common Control Demo", 0    ; the name of our window
    ProgressClass     db "msctls_progress32",0
    Message         db "Finished!",0
    TimerID         dq 0

; _________________________________________________________________________
; uninitialized variables

.data?
    CommandLine         LPSTR ?
    hInstance           HINSTANCE ?
    hIcon               HICON ?
    hCursor             HCURSOR ?
    hProgress         HANDLE ?
    hStatus             HANDLE ?
    CurrentStep         dq ?

.code

WinMainCRTStartup proc
   
    invoke  GetModuleHandle, NULL
    mov     hInstance, rax
   
    invoke  GetCommandLine
    mov     CommandLine, rax
   
    invoke  WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT
    invoke  ExitProcess, eax
   
    ret

WinMainCRTStartup endp

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
   
    LOCAL wcex:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hWnd:HWND
   
    invoke  LoadIcon, NULL, IDI_APPLICATION
    mov     hIcon, rax
    invoke  LoadCursor, NULL, IDC_ARROW
    mov     hCursor, rax
   
    mov     wcex.cbSize, sizeof WNDCLASSEX
    mov     wcex.style, CS_HREDRAW or CS_VREDRAW
    lea     rdi, WndProc
    mov     wcex.lpfnWndProc, rdi;offset WndProc
    mov     wcex.cbClsExtra, NULL
    mov     wcex.cbWndExtra, NULL
    mov     rax, hInst
    mov     wcex.hInstance, rax
    mov     rax, hIcon
    mov     wcex.hIcon, rax;hIcon
    mov     rbx, hCursor
    mov     wcex.hCursor, rbx;hCursor
    mov     wcex.hbrBackground, COLOR_APPWORKSPACE
    mov     wcex.lpszMenuName, NULL
    lea     rdi, ClassName
    mov     wcex.lpszClassName, rdi;offset ClassName
    mov     wcex.hIconSm, rax;hIcon
    invoke  RegisterClassEx, addr wcex
   
    invoke  CreateWindowEx,WS_EX_CLIENTEDGE, \
                    addr ClassName, \
                    addr AppName, \
                    WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE, \
                    CW_USEDEFAULT, \
                    CW_USEDEFAULT, \
                    CW_USEDEFAULT, \
                    CW_USEDEFAULT, \
                    NULL, \
                    NULL, \
                    hInst, \
                    NULL
    mov     hWnd, rax
   
    invoke  ShowWindow, hWnd, SW_SHOWNORMAL
    invoke  UpdateWindow, hWnd
   
    .while TRUE
        invoke  GetMessage, addr msg, NULL, 0, 0
        .if (rax == 0)
            .break
        .endif
        invoke  TranslateMessage, addr msg
        invoke  DispatchMessage, addr msg
    .endw
   
    mov     rax, msg.wParam
   
    ret

WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
   
    .if uMsg==WM_CREATE
        invoke CreateWindowEx, \
                        NULL, \
                        addr ProgressClass, \
                        NULL, \
                        WS_CHILD+WS_VISIBLE, \
                        100, \
                        200, \
                        300, \
                        20, \
                        hWnd, \
                        IDC_PROGRESS, \
                        hInstance, \
                        NULL
        mov hProgress, rax
       
        mov rax, 1000
        mov CurrentStep, rax
        shl rax, 16
       
        invoke SendMessage, hProgress, PBM_SETRANGE, 0, rax
        invoke SendMessage, hProgress, PBM_SETSTEP, 10, 0
       
        invoke CreateStatusWindow, WS_CHILD+WS_VISIBLE, NULL, hWnd, IDC_STATUS
        mov hStatus, rax
        invoke SetTimer, hWnd, IDC_TIMER, 100, NULL
        mov TimerID, rax
    .elseif uMsg==WM_DESTROY
        invoke  PostQuitMessage, NULL
        .if TimerID {} 0
            invoke KillTimer, hWnd, TimerID
        .endif
    .elseif uMsg==WM_TIMER
        invoke SendMessage, hProgress, PBM_STEPIT, 0, 0
        sub CurrentStep, 10
        .if CurrentStep==0
            invoke KillTimer, hWnd, TimerID
            mov TimerID, 0
            invoke SendMessage, hStatus, SB_SETTEXT, 0, addr Message
            invoke MessageBox, hWnd, addr Message, addr AppName, MB_OK+MB_ICONINFORMATION
            invoke SendMessage, hStatus, SB_SETTEXT, 0, 0
            invoke SendMessage, hProgress, PBM_SETPOS, 0, 0
        .endif
    .else
        invoke  DefWindowProc, hWnd, uMsg, wParam, lParam
        ret
    .endif
    xor eax, eax
    ret

WndProc endp

end


I used this way because I'm trying to stay true to the original
QuoteWS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE

Which one is the "right" way; this or something else:
WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_VISIBLE
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
BlueDeviL Github

jj2007

Thanks for posting complete code, BlueDevil. Here is my output:

*** assembling LineTooLong as Masm64 SDK source ***
*** linker options: [/entry:WinMainCRTStartup] ***
Assembling: Tmp_File.asm
*** linking LineTooLong.obj - no resources ***
*** success ***


No error message.

And yes, flags must be or'ed, not added, for obvious reasons.

zedd151

Quote from: bluedevil on September 14, 2022, 07:45:53 AM
Which one is the "right" way; this or something else:
WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_VISIBLE
I've always used 'or' myself, which I believe is more proper.

jj2007

So, where is the "line too long" error message? I can't see any, even when using...

    invoke  CreateWindowEx,\
    WS_EX_CLIENTEDGE, \

... as in the example above where you claimed that the (unknown) assembler throws it.

bluedevil

Quote from: jj2007 on September 14, 2022, 07:57:02 AM
So, where is the "line too long" error message? I can't see any, even when using...

    invoke  CreateWindowEx,\
    WS_EX_CLIENTEDGE, \

... as in the example above where you claimed that the (unknown) assembler throws it.

This is my makeit.bat file for this example
@echo off

set appname=TUTE18

del %appname%.obj
del %appname%.exe

REM \masm64\bin64\rc.exe /v %appname%.rc
REM \masm64\bin64\Cvtres.exe /machine:x64 DialogWithManifest.res

\masm64\bin64\ml64.exe /c %appname%.asm

\masm64\bin64\link.exe /SUBSYSTEM:WINDOWS /LARGEADDRESSAWARE %appname%.obj

dir %appname%.exe

pause


And here is the full output

Quote
C:\> makeit.bat

Microsoft (R) Macro Assembler (x64) Version 14.33.31629.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Assembling: TUTE18.asm
TUTE18.asm(146) : error A2039:line too long
Microsoft (R) Incremental Linker Version 14.33.31629.0
Copyright (C) Microsoft Corporation.  All rights reserved.

LINK : fatal error LNK1181: cannot open input file 'TUTE18.obj'
Volume in drive C has no label.
Volume Serial Number is 4CC4-1770

Directory of C:\MASM64\MyProjects\Iczelion\TUTE18

File Not Found
Press any key to continue . . .
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
BlueDeviL Github

bluedevil

M$ Docs says

Quote
line too long

A source-file line exceeded the limit of 512 characters.

If multiple physical lines are concatenated with the line-continuation character ( \ ), then the resulting logical line is still limited to 512 characters.
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
BlueDeviL Github

bluedevil

@jj
change here:

    invoke  CreateWindowEx,WS_EX_CLIENTEDGE, \
                    addr ClassName, \
                    addr AppName, \
                    WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_VISIBLE, \
                    CW_USEDEFAULT, \
                    CW_USEDEFAULT, \
                    CW_USEDEFAULT, \
                    CW_USEDEFAULT, \
                    NULL, \
                    NULL, \
                    hInst, \
                    NULL
    mov     hWnd, rax


to this:

invoke  CreateWindowEx, \
                WS_EX_CLIENTEDGE, \
                addr ClassName, \
                addr AppName, \
                WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_VISIBLE, \
                CW_USEDEFAULT, \
                CW_USEDEFAULT, \
                CW_USEDEFAULT, \
                CW_USEDEFAULT, \
                NULL, \
                NULL, \
                hInst, \
                NULL


but not this:
Quote from: jj2007 on September 14, 2022, 07:57:02 AM
    invoke  CreateWindowEx,\
    WS_EX_CLIENTEDGE, \
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
BlueDeviL Github

zedd151

Quote
If multiple physical lines are concatenated with the line-continuation character ( \ ), then the resulting logical line is still limited to 512 characters.
I wonder if that includes all the formatting 'whitespace'.
In that case, try
    invoke  CreateWindowEx,WS_EX_CLIENTEDGE, addr ClassName, addr AppName, \
                    WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_VISIBLE, \
                    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, \
                    NULL, NULL, hInst, NULL
    mov     hWnd, rax



I don't have 64 setup on this computer at the moment, else I'd try it to verify that it works.

bluedevil

M$ Docs are pretty clear actually :/
I thought if there is a limitation on  "invoke", but frankly the limitation is in ML itself. And yes is counts the white space!
..Dreams make the future
But the past never lies..
BlueDeviL // SCT
My Code Site:
BlueDeviL Github

zedd151

Quote from: bluedevil on September 14, 2022, 09:00:02 AM
And yes is counts the white space!
I usually try to never exceed about 100 chars/line in  my sources, using equates as I shown above or shorter variable names if possible to reduce line length. (So I don't have to scroll to see the rest of the line, no wordwrap used here) I rarely use a line continuation "/".


example:
    MakeButton proc hWin:dword, bnx:dword, bsx:dword, x:dword, y:dword, hi:dword, id:dword
    local hndl:dword
        push esi
        push edi
        push ebx
        push edx
        push ecx
        invoke CreateWindowEx, 0, bnx, 0, bsx, x, y, 64, 64, hWin, id, hi, 0
        mov hndl, eax
        ...code continues...

This is just an example, you don't have to do it this way though. Yes I use 0 rather than NULL. Saves space and resolves to zero in either case anyway.

jj2007

No error message, sorry :cool:

Microsoft (R) Macro Assembler (x64) Version 14.30.30705.0
Copyright (C) Microsoft Corporation.  All rights reserved.

Assembling: LineTooLong.asm
Il volume nell'unità J è Acer
Numero di serie del volume: 2A34-6C3C

Directory di C:\Masm64\Members\blue_devil

14.09.22  01:31             3,072 LineTooLong.exe
               1 File          3,072 byte