Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29111 Discussions

How do I print an integer in a Win32 MessageBox

brianreinhold
Novice
1,095 Views

I have this code

                ret = SetWindowLongPtr(hwnd, GWLP_USERDATA, lData)
                if (ret == 0) then
                    err = GetLastError()
                    write(errMsg, '(I0)') err  ! Convert integer to string
                    errMsg = trim(adjustl(errMsg)) 
                    errMsg = errMsg // c_null_char
                    ret = MessageBox(hwnd, "SetWindowLongPtr in WM_CREATE failed! Error Code: "C // errMsg, "Error"C, MB_OK)
                end if

I am getting an error '6' here which I can see when doing a line-by line debug. That error is another problem, but regardless of what I do I cannot get that '6' to be displayed in the MessageBox. I have tried multiple different combinations of trying to make it into a C string, but all I get in the end is the text followed by nothing.

Have tried // char(0) in place of c_null_char

I have use iso_c_binding
errMsg is declared as char(64)  - I have tried different sizes

Anyone know how to do what should be such a simple task??

 

I

0 Kudos
1 Solution
GVautier
New Contributor III
1,051 Views

You should use

write(errMsg, '(I0)') err  ! Convert integer to string
errMsg = trim(errMsg) // c_null_char
ret = MessageBox(hwnd, "SetWindowLongPtr in WM_CREATE failed! Error Code: "C // errMsg, "Error"C, MB_OK)
or
write(errMsg, '(I0,a)') err,c_null_char  ! Convert integer to string
ret = MessageBox(hwnd, "SetWindowLongPtr in WM_CREATE failed! Error Code: "C // errMsg, "Error"C, MB_OK)
or
write(errMsg, '(I0)') err  ! Convert integer to string
ret = MessageBox(hwnd, "SetWindowLongPtr in WM_CREATE failed! Error Code: "C // trim(errMsg)//c_null_char, "Error"C, MB_OK)

With your code the null character can't be appended to errMsg because errMsg//c_null_char  has a length of 65 characters so it is truncated to 64 when assigned back to errMsg.

View solution in original post

10 Replies
GVautier
New Contributor III
1,052 Views

You should use

write(errMsg, '(I0)') err  ! Convert integer to string
errMsg = trim(errMsg) // c_null_char
ret = MessageBox(hwnd, "SetWindowLongPtr in WM_CREATE failed! Error Code: "C // errMsg, "Error"C, MB_OK)
or
write(errMsg, '(I0,a)') err,c_null_char  ! Convert integer to string
ret = MessageBox(hwnd, "SetWindowLongPtr in WM_CREATE failed! Error Code: "C // errMsg, "Error"C, MB_OK)
or
write(errMsg, '(I0)') err  ! Convert integer to string
ret = MessageBox(hwnd, "SetWindowLongPtr in WM_CREATE failed! Error Code: "C // trim(errMsg)//c_null_char, "Error"C, MB_OK)

With your code the null character can't be appended to errMsg because errMsg//c_null_char  has a length of 65 characters so it is truncated to 64 when assigned back to errMsg.

brianreinhold
Novice
960 Views

I did this

    integer*4   err
    character(len = 16) :: errStr
    character(len = 16, kind = c_char) :: errMsg
         .... (some more code)

                ret = SetWindowLongPtr(hwnd, 0, lData)
                if (ret == 0) then
                    err = GetLastError()
                    write(errStr, '(I0)') err  ! Converts 'err' integer to string
                                               ! WRITE won’t work directly on a c_char character variable so
                                               ! need two variable, errStr and errMsg. The latter is declared
                                               ! as a c-type character, errStr is not.
                                               ! Note that Fortran requires a separate buffer for integer-to-string conversion.
                    errMsg = trim(adjustl(errStr)) // C_NULL_CHAR  ! Trim off extra and Null-terminate
                    ret = MessageBox(ghwndMain,"SetWindowLongPtr failed with error " // errMsg, &
                                    "Error"C, MB_OK)
                end if

for the commented reasons and it worked. Your solution looks a lot simpler but it also looks like something I once tried. I have not tried it again but its relative simplicity makes it worth a retry.
I tried your middle solution

write(errMsg, '(I0,a)') err,c_null_char  ! Convert integer to string
ret = MessageBox(hwnd, "SetWindowLongPtr in WM_CREATE failed! Error Code: "C // errMsg, "Error"C, MB_OK)

and it did not work. errMsg was declared as 

'character(16) errMsg'

0 Kudos
andrew_4619
Honored Contributor III
1,018 Views
write(errMsg, '(I0)') err  ! Convert integer to string
ret = MessageBox(hwnd, "SetWindowLongPtr in WM_CREATE failed! Error Code: "// trim(errMsg)//c_null_char, "Error"C, MB_OK)

I would expect the null in the middle of the string after ...Error Code: " would cause an issue giving a shortened string (not tested)

0 Kudos
GVautier
New Contributor III
995 Views

The null character is at the end of the message string

"SetWindowLongPtr in WM_CREATE failed! Error Code: "// trim(errMsg)//c_null_char

The second argument "Error"c is the messagebox window caption

0 Kudos
andrew_4619
Honored Contributor III
960 Views

I think you should read the previous posts again. My post had the spurious C removed but several of the previous posts have it.

andrew_4619_0-1747226417205.png

 

0 Kudos
GVautier
New Contributor III
922 Views

OK I missed that other error in code. The error number will never be displayed.

write(errMsg, '(I0,a)') err,c_null_char  ! Convert integer to string
ret = MessageBox(hwnd, "SetWindowLongPtr in WM_CREATE failed! Error Code: " // errMsg, "Error"C, MB_OK)

I would have written this portion of code like that

write(errMsg, '(a,I0)') "SetWindowLongPtr in WM_CREATE failed! Error Code: ",err  ! Convert integer to string
ret = MessageBox(hwnd, trim(errMsg)//c_null_char, "Error"C, MB_OK)

I always convert to C string only where it is necessary.

0 Kudos
andrew_4619
Honored Contributor III
916 Views

I never use that "C" it is not standard Fortran. For MessageBox and some similar functions I tend to make a simple wrapper routine that internal handles string termination so the caller can work with Fortran things not C things and you can minimise the SDK clutter in the code.

0 Kudos
GVautier
New Contributor III
914 Views

So do  I, I even create a cstring() function that returns the fortran string appended with the char(0). So on Fortran side, I have only Fortran strings.

0 Kudos
brianreinhold
Novice
761 Views

@andrew_4619 I have kept to my solution and have removed the "C in the MessageBox in favor of  c_null_char to make it more standardized.

But the real issue I had with this process was converting the fortran integer to a C string for MessageBox. The final solution to that headache was that I needed to declare two different types of strings, one for fortran and one for C. Printing strings into MessageBox was never a problem.

Who decides what is the accepted solution? I did not check that option. I had tried all those options of the accepted solution and none of them worked before I even posted this issue. The prints worked fine but no number was displayed.

0 Kudos
GVautier
New Contributor III
749 Views

This code doesn't work?

write(errMsg, '(I0)') err  ! Convert integer to string
ret = MessageBox(hwnd, "SetWindowLongPtr in WM_CREATE failed! Error Code: "//trim(errMsg)//c_null_char, "Error"C, MB_OK)

 

0 Kudos
Reply
OSZAR »