Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Baffling problem - scroll bars, namespaces etc

82 views
Skip to first unread message

Paul N

unread,
Oct 9, 2014, 6:15:08 PM10/9/14
to
I've hit a baffling problem, and I'm not sure if it relates to Windows or to C++.

I had the following in my main .cpp file:

static SCROLLINFO si;

void mySetScrollRangeAndPage(HWND hWnd, int nBar, int nMin, int nMax, UINT nPage) {
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = nMin;
si.nMax = nMax;
si.nPage = nPage;
si.nPos = nMin;
SetScrollInfo(hWnd, nBar, &si, TRUE);
}

It worked fine, setting a scroll bar.

I wanted to put the scroll bar stuff in a separate file, so that I could use it with other programs. So I copied it to Scroller.cpp, and put the function (but not the definition of si) between lines "namespace Scroller {" and "}". (I admit I'm fairly new to namespaces.) Unfortunately the first call to this function does not work - si is loaded up OK but the scroll bar is not set, it stays at a range of 0 to 100. Later calls seem to work OK so if I do the first one again later everything works, but I can't understand why the first one goes wrong.

If I put "SCROLLINFO si;" in the main .cpp file and "extern SCROLLINFO si;" in Scroller.cpp, this also works OK. I don't understand why having it in one .cpp file works and having it in the other doesn't.

Can anyone help?

I would cross-post to comp.lang.c++ and comp.os.ms-windows.programmer.win32, but Google doesn't seem to do that anymore.

Thanks.
Paul.

Barry Schwarz

unread,
Oct 9, 2014, 7:19:56 PM10/9/14
to
On Thu, 9 Oct 2014 15:14:51 -0700 (PDT), Paul N <gw7...@aol.com>
wrote:

>I've hit a baffling problem, and I'm not sure if it relates to Windows or to C++.
>
>I had the following in my main .cpp file:
>
>static SCROLLINFO si;
>
>void mySetScrollRangeAndPage(HWND hWnd, int nBar, int nMin, int nMax, UINT nPage) {
>si.cbSize = sizeof(si);
>si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
>si.nMin = nMin;
>si.nMax = nMax;
>si.nPage = nPage;
>si.nPos = nMin;
>SetScrollInfo(hWnd, nBar, &si, TRUE);
>}
>
>It worked fine, setting a scroll bar.

Please set your newsreader to a line length less than 80.

>I wanted to put the scroll bar stuff in a separate file, so that I could use it with other programs. So I copied it to Scroller.cpp, and put the function (but not the definition of si) between lines "namespace Scroller {" and "}". (I admit I'm fairly new to namespaces.) Unfortunately the first call to this function does not work - si is loaded up OK but the scroll bar is not set, it stays at a range of 0 to 100. Later calls seem to work OK so if I do the first one again later everything works, but I can't understand why the first one goes wrong.

Scroller.cpp should not compile. The name si is unknown during the
compilation phases. How can mySet... change the contents of si in
main.cpp?

Adding the line
extern SCROLLINFO si;
will solve the compile problem but create a link problem. Since si in
main.cpp is static, it has internal linkage and its name is never
"exported" to the linker to resolve the name referenced in
Scroller.cpp.

>If I put "SCROLLINFO si;" in the main .cpp file and "extern SCROLLINFO si;" in Scroller.cpp, this also works OK. I don't understand why having it in one .cpp file works and having it in the other doesn't.

Having it in the other what? Defining a global object with external
linkage in one cpp file and declaring it external in every other cpp
file that needs to access it is the usual technique. Your first
attempt did not do this.

>Can anyone help?
>
>I would cross-post to comp.lang.c++ and comp.os.ms-windows.programmer.win32, but Google doesn't seem to do that anymore.

Get a real newsreader.

--
Remove del for email

Rick C. Hodgin

unread,
Oct 9, 2014, 7:22:37 PM10/9/14
to
It's possible your packed structure size is
different. Some use 16 byte alignment. Since
it's compiling in two source files, the alignment
could be off causing your member assignment
to be misaligned.

Check the compiler switches for packed
structure alignment. Or compare the sizeof()
from both locations. They should be the same.

Best regards,
Rick C. Hodgin

Paul N

unread,
Oct 13, 2014, 5:36:02 PM10/13/14
to
They do both appear to be the same size, so I don't think that's the problem. But I don't know what is!

Paul N

unread,
Oct 13, 2014, 5:51:13 PM10/13/14
to
Thanks Barry for your help, and sorry for not getting back to you sooner.

On Friday, 10 October 2014 00:19:56 UTC+1, Barry Schwarz wrote:
> On Thu, 9 Oct 2014 15:14:51 -0700 (PDT), Paul N <gw7...@aol.com>
>
> wrote:
>
>
>
> >I've hit a baffling problem, and I'm not sure if it relates to Windows or to C++.
>
> >
>
> >I had the following in my main .cpp file:
>

I'll call this version one...

>
> >static SCROLLINFO si;
>
> >
>
> >void mySetScrollRangeAndPage(HWND hWnd, int nBar, int nMin, int nMax, UINT nPage) {
>
> >si.cbSize = sizeof(si);
>
> >si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
>
> >si.nMin = nMin;
>
> >si.nMax = nMax;
>
> >si.nPage = nPage;
>
> >si.nPos = nMin;
>
> >SetScrollInfo(hWnd, nBar, &si, TRUE);
>
> >}
>
> >
>
> >It worked fine, setting a scroll bar.
>
>
>
> Please set your newsreader to a line length less than 80.

I'm afraid I don't think this is an option, see below...

Anyhow, moving on to version two:

> >I wanted to put the scroll bar stuff in a separate file, so that I could use it with other programs. So I copied it to Scroller.cpp, and put the function (but not the definition of si) between lines "namespace Scroller {" and "}". (I admit I'm fairly new to namespaces.) Unfortunately the first call to this function does not work - si is loaded up OK but the scroll bar is not set, it stays at a range of 0 to 100. Later calls seem to work OK so if I do the first one again later everything works, but I can't understand why the first one goes wrong.
>
>
>
> Scroller.cpp should not compile. The name si is unknown during the
>
> compilation phases. How can mySet... change the contents of si in
>
> main.cpp?
>

Sorry, I didn't explain that well. In version two, all the code above is in Scroller.cpp. So the function should find si OK. Interestingly, while the code compiled, the "IntelliSense" didn't seem to know the members of a SCROLLINFO. I added "#include <Windows.h>" and this sorted out the IntelliSense but didn't aoppear to affect how the program compiled or ran. A clue or just another mystery?


>
> Adding the line
>
> extern SCROLLINFO si;
>
> will solve the compile problem but create a link problem. Since si in
>
> main.cpp is static, it has internal linkage and its name is never
>
> "exported" to the linker to resolve the name referenced in
>
> Scroller.cpp.
>
This seems to be version three, which I describe now...

>
> >If I put "SCROLLINFO si;" in the main .cpp file and "extern SCROLLINFO si;" in Scroller.cpp, this also works OK. I don't understand why having it in one .cpp file works and having it in the other doesn't.
>
>
>
> Having it in the other what? Defining a global object with external
>
> linkage in one cpp file and declaring it external in every other cpp
>
> file that needs to access it is the usual technique. Your first
>
> attempt did not do this.
>

I meant I didn't see why having the definition in one .cpp file and linked to the function in the other .cpp file worked; whereas having the definition in the same .cpp file as the function failed to work, in the sense that it compiles and links but fails to work on the first call (and does work on later calls).

I'm trying to create a Scroller.cpp file that I can use with other programs rather than having to re-write the scrolling code each time. It would seem perfectly rasonable for the code to include the definition of the variables it needs, instead of needing each program to provide these. I'm baffled as to why it doesn't work.

>
> >Can anyone help?
>
> >
>
> >I would cross-post to comp.lang.c++ and comp.os.ms-windows.programmer.win32, but Google doesn't seem to do that anymore.
>
>
>
> Get a real newsreader.
>

If Google mess about with their interface any more I will look into this. It seems to have been gradually going downhill.

Paavo Helde

unread,
Oct 14, 2014, 1:20:52 AM10/14/14
to
Paul N <gw7...@aol.com> wrote in
news:340b1d1a-0321-4216...@googlegroups.com:

>> >I had the following in my main .cpp file:
>> >static SCROLLINFO si;
>> >I wanted to put the scroll bar stuff in a separate file, so that I
>> >could
> use it with other programs. So I copied it to Scroller.cpp, and put
> the function (but not the definition of si) between lines "namespace
> Scroller {" and "}". (I admit I'm fairly new to namespaces.)
> Unfortunately the first call to this function does not work - si is
> loaded up OK but the scroll bar is not set, it stays at a range of 0
> to 100.
>> >If I put "SCROLLINFO si;" in the main .cpp file and "extern
>> >SCROLLINFO
> si;" in Scroller.cpp, this also works OK. I don't understand why
> having it in one .cpp file works and having it in the other doesn't.

This seems like some confusion with 'static' and/or namespaces. Or it
might even be somehow related to the the global initialization fiasco
(though it does not look likely).

Most probably you have two definitions of 'si', one in global namespace
and one in your namespace, or one declared static and another not. Please
make sure you have only one definition of 'si' and that this definition
and all 'extern' declarations appear in the same namespace. Or maybe only
MSVC thinks you have two definitions - rebuild the project once (instead
of just building), just to make sure MSVC is not messing something up by
itself.

In another post you worried about IntelliSense, this is an independent
feature which does not really work 100% reliably. Do not turn too much
attention to it.

Cheers
Paavo


Rick C. Hodgin

unread,
Oct 14, 2014, 4:17:22 AM10/14/14
to
Try passing parameters to a function and using
a local variable. Or include a pointer and
populate the thing being pointed to so it is
never a question.

Wouter van Ooijen

unread,
Oct 14, 2014, 4:26:05 AM10/14/14
to
Paul N schreef op 10-Oct-14 12:14 AM:
> I've hit a baffling problem, and I'm not sure if it relates to Windows or to C++.
>
> I had the following in my main .cpp file:
>
> static SCROLLINFO si;
>
> void mySetScrollRangeAndPage(HWND hWnd, int nBar, int nMin, int nMax, UINT nPage) {
> si.cbSize = sizeof(si);
> si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
> si.nMin = nMin;
> si.nMax = nMax;
> si.nPage = nPage;
> si.nPos = nMin;
> SetScrollInfo(hWnd, nBar, &si, TRUE);
> }
>
> It worked fine, setting a scroll bar.
>
> I wanted to put the scroll bar stuff in a separate file, so that I could use it with other programs. So I copied it to Scroller.cpp, and put the function (but not the definition of si) between lines "namespace Scroller {" and "}". (I admit I'm fairly new to namespaces.) Unfortunately the first call to this function does not work - si is loaded up OK but the scroll bar is not set, it stays at a range of 0 to 100. Later calls seem to work OK so if I do the first one again later everything works, but I can't understand why the first one goes wrong.
>
> If I put "SCROLLINFO si;" in the main .cpp file and "extern SCROLLINFO si;" in Scroller.cpp, this also works OK. I don't understand why having it in one .cpp file works and having it in the other doesn't.

Juk, ultra-long lines :(

Is that first call that does not work started by main() or by some
global constructor? If the last, you have been hit by the 'undefined
order of ininitialization of global objects' bug/problem/feature: the
order in which the global objects of different compilation units are
initialized is undefined. Within a single compilation unit it is
top-down, so your one-file version did not suffer from this problem.

Wouter

Paul N

unread,
Oct 14, 2014, 5:34:08 PM10/14/14
to
On Tuesday, 14 October 2014 09:17:22 UTC+1, Rick C. Hodgin wrote:
> Try passing parameters to a function and using
>
> a local variable. Or include a pointer and
>
> populate the thing being pointed to so it is
>
> never a question.

I've now tried it with a static local variable and this seems to work. So perhaps I'll leave it at that. I'm still baffled as to why the other version did not work, however, plus have a slight nagging feeling that there still might be something wrong, as I don't see how I've "fixed" it.

Thanks.
Paul.

0 new messages