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

Trouble with GetWindowText

llynisa
Beginner
6,248 Views

I am attempting to read the text of a button in order to transfer it to another. The text of the first, IDCANCEL, is set in the resource file as Cancel without the inverted commas. When I use the command to read the text into the character*20 ButtonStr:

lBtnStr = GetWindowText(hButton, ButtonStr, 20) ! Get Button text.

The return value of lBtnStr is 19, rather than the expected 6.

The 7th to 20th characters of ButtonStr are not uniform blanks, do not contain any nulls = char(0) but do contain the occasional alphanumeric character.

When subsequently written into another button, it is treated as being of length 19, not 6, which ruins the centering.

Other WinAPIs are no better or worse, with GetWindowTextLength returning 280 and GetDlgItemText 19.

Any ideas please?

Llynisa

0 Kudos
31 Replies
Anonymous66
Valued Contributor I
4,359 Views
How are you setting the text for IDCANCEL? It sounds like thetext for IDCANCELis improperly terminated.
0 Kudos
Michael_J_Slater__In
New Contributor I
4,359 Views
Maybe you have leading/trailing blanks that are inserted in the string. Try:
lBtnStr = TRIM (ADJUSTL (GetWindowText(hButton, ButtonStr, 20)))
0 Kudos
llynisa
Beginner
4,359 Views
Thanks for replying.
The text is set by using the control wizard to generate the button- it is not possible to use C strings in setting the text of controls using the control wizard, although I would have liked tohave doneso. A sort of solution is to use the command:

lRet = DlgSet (XDlg, IDCANCEL, 'Cancel'C)

immediately after the initialisation of the dialogue.

lBtnStr = TRIM(ADJUSTL(GetWindowText(hButton, ButtonStr, 20)

returns 19 as before. The trouble is a series of non-displaying characters with the occasional alphanumeric character that follow Cancel in the string.

Llynisa
0 Kudos
Anonymous66
Valued Contributor I
4,359 Views
Llynisa,
I don't know whythe string isn't automatically being null terminated, but yousolve this issue by adding a null at the end of the string yourself.

Simply change your code to set the text for IDCANCEL to the following:
lRet = DlgSet (XDlg, IDCANCEL, 'Cancel\0'C)

Annalee
0 Kudos
llynisa
Beginner
4,359 Views
Annalee,

Well, thanks - I think that you have provided the clue to the answer - if when using thecontrol wizard one enters the button text of IDCANCEL exactly as:

Cancel\0'C

that solves the problem. In my 50th year of Fortran (and other) programming, I never realised that one could produce a C stringby that method - I have always used 'Cancel'C or 'Cancel'//char(0). So I keep on learning in my dotage.

Thanks again

Llynisa


0 Kudos
Steven_L_Intel1
Employee
4,359 Views
There are several ways to get a NUL-terminated string. Some of them are extensions, some are standard. By default, string literals are NOT NUL-terminated in Fortran.

The way I would recommend is to concatenate a NUL chararacter. You can use CHAR(0) but I prefer to use the named constant C_NULL_CHAR from intrinsic module ISO_C_BINDING. This is portable and standard-confortming. Just remember to use TRIM if the value might have trailing blanks.

You can use the 'string'C syntax, which is an extension in the Intel compilers and not guaranteed to be portable.

Last, the method Annalee mentioned requires that the option /assume:bscc be in effect. This is not the default and I have a personal bias against code that requires a compile option. It is, of course, an extension.
0 Kudos
Anonymous66
Valued Contributor I
4,359 Views

Lynisa,

Steve is absolutely right. You are much better off concatenating the null character to the end of your string in your code rather than having it as a part of the string you type in.

'\0' always works with the 'string'C syntax as far as I'm aware, but the /assume:bscc option is necessary when using it or other \escapes in standard Fortran stings.

0 Kudos
Steven_L_Intel1
Employee
4,359 Views
Yes, that's correct. The escapes work in ''C strings, but those are also NUL terminated by default. If you're using variables, and not quoted string literals, concatenation is the right approach.
0 Kudos
anthonyrichards
New Contributor III
4,359 Views
You refer to a 'control wizard' which is used to generate the button.
In my experience, the resource editor supplied with Visual Studio is the one developed for C++ and so being C-based, it always makes text strings in static text, button controls etc. null terminated when using it to add controls to a dialog. So I do not understand how it can be responsible for generating non-null-terminated strings on your controls. If, after creation, you are subsequently changing the text using SETTEXT messages within your program and supply a non-null-terminated string, then that might be the source of your problem.
0 Kudos
llynisa
Beginner
4,359 Views

Steve, Annalee,

Thanks for setting things straight on C strings. However, I must withdraw my statement in my last post that I could set a C string using the control wizard I was writing in haste late in the evening.

No matter how I try, I cannot get a C string set by the control wizard. so my problem moves on to being solved by either resetting the buttton text using eg:

lRet = DlgSet (XDlg, IDCANCEL, 'Cancel'C)

or by working out how to read the button text correctly when it is not a C string.

If this were a one-off problem I would reset the button text, but my reading statement is in a subroutine that I expect to use on a considerable number of buttons in several programs. Hence I am really looking for a fool-proof way to read a button text without a null but with a variety of unwanted characters following the useful parts.

Llynisa

0 Kudos
anthonyrichards
New Contributor III
4,359 Views
Pleae can you give more details concerning the 'control wizard' to which you refer?
0 Kudos
llynisa
Beginner
4,359 Views

Tony,

These posts seem to have got out of order.

Yes, sorry, I should have called it the resource editior, but whats turning up on the buttons are not C-strings unless I reset them, which I have not, as you can see in the code I sent you the other day. Is it anything to do with my still using CVF6.6C2?

Still puzzled

Llynisa aka BearofLittleBrain

0 Kudos
anthonyrichards
New Contributor III
4,359 Views
Ah, good old 6.6C! I have that as well (but I start new projects using Intel Composer now).
Can you post your resource .RC and .H header file so that I can see how it displays on my version?

I attach screen shot of a debug run of a simple dialog where I press an 'Apply' button which then gets the text from the 'Exit' button. A syou can see the returned string length is 4 and the memory displayed at the location of the string shows no nasty characters after the fourth one.

(just watched Atlantis launch for the last time - great TV pictures from NASA).
0 Kudos
llynisa
Beginner
4,359 Views
Well, I am still puzzled as to why we get different results and hope that someone can point out my errr/stupidity

Files attached.
0 Kudos
IanH
Honored Contributor III
4,359 Views
Why do your buttons have the BS_OWNERDRAW style? What happens if you remove that style?

0 Kudos
llynisa
Beginner
4,359 Views
Removing BS_OWNERDRAW has no effect except that I can't redraw the button. GetWindowText returns 19 as before. I attach an image of what it looks like if I don't get the correct length of button text. As you may see, I am trying to colour pushbuttons, and although it is a rather simplified solution, it seems to be working well except for the text length bug.
0 Kudos
llynisa
Beginner
4,359 Views
I can't open my own .bmp file when I click on it in my last post, so am repeating it as .jpg
0 Kudos
anthonyrichards
New Contributor III
4,359 Views
In my experience, Windows will not let you run an EXE where command buttons have been given the BS_OWNERDRAW style, even if you can select Ownerdraw from the Properties sheets.
0 Kudos
llynisa
Beginner
4,359 Views
Tony,

Yes, you are quite right on that normally, but if one adds Jugoslav's XFLogm one can run them, as shown in his DlgTest program in his XEffort examples. I did not need to add the whole of his XEffort for this, just XFLogm.

If I can crack this one, I hope to persuade you to reissue your Knowledge Base article How to customize dialog box colors using subclassing with my additions to colour the buttons.

Llynisa aka BearofLittleBrain
0 Kudos
IanH
Honored Contributor III
4,158 Views
In my experience, Windows will not let you run an EXE where command buttons have been given the BS_OWNERDRAW style, even if you can select Ownerdraw from the Properties sheets.

I don't follow what you mean by the above.

In terms of the original post - attached is a small fortran "program" that loads and shows the dialog defined by the resource file attached earlier in the thread.

  • To dismiss the dialog and exit the program, click on the dialog box's client area with the middle button of the mouse. I appreciate this is a bit bizarre, but this is just a simple test framework.
  • If you click on the dialog box's client area with the left mouse button then a message box will pop-up showing the results of querying the the text of the control with identifier IDCANCEL.
There's a place holder procedure for handling the owner draw button controls.

For the resource file as posted, this program reports that the length of the cancel control's text is six characters, as expected. If the OP is seeing something different with their program, then it is probable something else in their program is changing the text length after the dialog box is created from the resource template (assuming the call to the WinGetDlgItemText api isn't being botched up somehow). Perhaps the dialog is being (sub|super)-classed? The last post mentions Xeffort - I'm not familiar with it, but perhaps it is doing something like that behind the scenes - the window text for an owner draw control would be a very convenient place to stash additional information for a super or sub-class.

Regardless, more help requires lots more context - post (perhaps a cutdown variant of) your code.

Note that you can examine the text of a control using Win32 diagnostic utilities, such as the Spy++ utility that is installed with (some versions of?) Visual Studio (if your edition/version doesn't have this utility then sysinternals and the like probably have something similar available for download). What do they say about the control's text?

DialogTestDeluxe.f90
0 Kudos
Reply