Windows App - C++

A

August1

No point has been missed, no insults have been offered to anyone, no
exclamations have been added for emphasis to convey a conviction, no
profanity has been offered, no "misconduct" has been presented. i do
however find some of the responses interesting.

regards
 
P

Phlip

August1 said:
No point has been missed, no insults have been offered to anyone, no
exclamations have been added for emphasis to convey a conviction, no
profanity has been offered, no "misconduct" has been presented. i do
however find some of the responses interesting.

Attempt to be gracious noted! Now answer questions about C++ here.
 
A

Alf P. Steinbach

* August1:
I'm beginning to approach Windows programming in C++. I've written
a short
application which is to do nothing more than demonstrate the Window
style being used. The child windows are not appearing within the
parent window. Could someone point out the cause?

Because you forgot to compile and run the program?

If you have any problems with compiling, ask in a compiler-specific
newsgroup.

If you have any problems getting the program to run, ask in a Windows-specific
newsgroup.


#include <windows.h>

For C++ always #define STRICT and NOMINMAX before this #include.

#include <string.h>

Preferentially use


#include <cstring>


long WINAPI MainWndProc(HWND,UINT,WPARAM,LPARAM);

HWND hWnd;

Don't use global variables.

HWND hwndEdit;
HWND hwndButton;
HWND hwndClearButton;
char szMessage[50] = "";

Here you're into buffer overflow territory; instead consider
std::string.


int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{

Check out your compiler's support for standard 'main'. g++ supports
that directly for Windows GUI application. Use standard 'main'.

WNDCLASS wc;
wc.lpszClassName = "Style1";
wc.lpfnWndProc = MainWndProc;
wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)( COLOR_WINDOW+1 );
wc.lpszMenuName = "";
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
RegisterClass(&wc);

A simpler way might be to use an initializer, "WNDCLASS wc = { ... };".

Anyway, to ensure all non-assigned fields are zero, declare it like


WNDCLASS wc = {0};



hWnd = CreateWindow("Style1","Border Demonstration",
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
185,265,NULL,NULL,hInstance,NULL);

hwndEdit = CreateWindow("EDIT",NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER | ES_LEFT,
10,10,155,20,hWnd,NULL,hInstance,NULL);

hwndButton = CreateWindow("BUTTON","Message",
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
10,40,35,35,hWnd,NULL,hInstance,NULL);

hwndClearButton = CreateWindow("BUTTON","Clear",
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
50,40,35,35,hWnd,NULL,hInstance,NULL);

Error checking might be a good idea... For example using a function

template< typename T >
inline void throwIf0( T const& x )
{
if( !x ) { throw std::runtime_error( "Ooops." ); }
}

Then

hWnd = CreateWindow("Style1","Border Demonstration",
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
185,265,NULL,NULL,hInstance,NULL);
throwIf0( hWnd );

of course with a 'catch' somewhere.

ShowWindow(hWnd,nCmdShow);

MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

Here should be cast to the return type, i.e.


}//end WinMain()



long WINAPI MainWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM
lParam)
{
HWND hwndCtl = (HWND)lParam;

Don't use C style casts.

In this case, use a reinterpret_cast or the appropriate system-specific
macro/function (off-topic hint: <windowsx.h>).

Anyway the logic is flawed: you don't yet have enough information to
say that this argument represents what you think it does. But it works.
With a bit of maintainance it will cease to work.

switch(msg)
{
case WM_COMMAND:
switch(wParam)
{
case BN_CLICKED:
if(hwndCtl == hwndButton)
{
strcpy(szMessage,"This program is an overlapped style Window.");

Buffer overflow?

Indentation!
 
P

Phlip

Alf said:
For C++ always #define STRICT and NOMINMAX before this #include.

And WIN32_LEAN_AND_MEAN!
Preferentially use

#include <cstring>

James Kanze points out don't use the C++-style C Library Headers unless you
really really mean it. Right now, in our legacy-code besotted world,
<cstring> is a portability dead spot, and <string.h> is everywhere you need
to be.
 
A

August1

You've been told that this is off-topic. Instead of acknowledging that
and apologizing, you argue. To what end? Do you think you'll
everybody's mind. Instead, what happens is this:


*plonk*

I've not laughed so heartily in about 1 month. Thanks to all.
regards
 
I

Ioannis Vranos

August1 said:
Hi,

I'm beginning to approach Windows programming in C++. I've written
a short
application which is to do nothing more than demonstrate the Window
style being used. The child windows are not appearing within the
parent window. Could someone point out the cause?


I am using .NET so I do not know these Win32 stuff. In any case,
comp.lang.c++ is about talking ISO C++, that is the pure C++ language as
defined by the ISO C++ standard.

For questions about the trillions of system specific applications of
C++, one should post the relevant newsgroups.

For example there are MS newsgroups for MS platform programming and in
particular MS provides a free newsgroup server


msnews.microsoft.com


with all the newsgroups regarding their platforms.


Just configure your newsgroup reader to access that server and find the
relevant newsgroups.


Also there are some of those MS newsgroups, and other non-MS newsgroups
about Win32 available in Usenet (Usenet is where you found this
newsgroup), just search for newsgroups with the word Win32 in your
newsgroup client.
 
E

E. Robert Tisdale

August1 wrote:

[Something that calls itself Default User wrote:]
You've been told that this is off-topic.
Instead of acknowledging that and apologizing, you argue. To what end?
Do you think you'll [change] everybody's mind.
Instead, what happens is this:

*plonk*

I've not laughed so heartily in about 1 month. Thanks to all.
regards

Please ignore our trolls.
They seem to think that it's fun to ambush new subscribers.

The comp.lang.c++ newsgroup is a good place to get bad advice
about Windows specific programming.
I hope the you found the redirection to more appropriate forums helpful.

Please come back to us
when you have specific questions about standard C++.
 
A

August1

Because you forgot to compile and run the program?
If you have any problems with compiling, ask in a compiler-specific
newsgroup.

If you have any problems getting the program to run, ask in a Windows-specific
newsgroup.


#include <windows.h>

For C++ always #define STRICT and NOMINMAX before this #include.

#include <string.h>

Preferentially use


#include <cstring>


long WINAPI MainWndProc(HWND,UINT,WPARAM,LPARAM);

HWND hWnd;

Don't use global variables.

HWND hwndEdit;
HWND hwndButton;
HWND hwndClearButton;
char szMessage[50] = "";

Here you're into buffer overflow territory; instead consider
std::string.


int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{

Check out your compiler's support for standard 'main'. g++ supports
that directly for Windows GUI application. Use standard 'main'.

WNDCLASS wc;
wc.lpszClassName = "Style1";
wc.lpfnWndProc = MainWndProc;
wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)( COLOR_WINDOW+1 );
wc.lpszMenuName = "";
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
RegisterClass(&wc);

A simpler way might be to use an initializer, "WNDCLASS wc = { ... };".

Anyway, to ensure all non-assigned fields are zero, declare it like


WNDCLASS wc = {0};



hWnd = CreateWindow("Style1","Border Demonstration",
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
185,265,NULL,NULL,hInstance,NULL);

hwndEdit = CreateWindow("EDIT",NULL,
WS_VISIBLE | WS_CHILD | WS_BORDER | ES_LEFT,
10,10,155,20,hWnd,NULL,hInstance,NULL);

hwndButton = CreateWindow("BUTTON","Message",
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
10,40,35,35,hWnd,NULL,hInstance,NULL);

hwndClearButton = CreateWindow("BUTTON","Clear",
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
50,40,35,35,hWnd,NULL,hInstance,NULL);

Error checking might be a good idea... For example using a function

template< typename T >
inline void throwIf0( T const& x )
{
if( !x ) { throw std::runtime_error( "Ooops." ); }
}

Then

hWnd = CreateWindow("Style1","Border Demonstration",
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
185,265,NULL,NULL,hInstance,NULL);
throwIf0( hWnd );

of course with a 'catch' somewhere.

ShowWindow(hWnd,nCmdShow);

MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;

Here should be cast to the return type, i.e.


}//end WinMain()



long WINAPI MainWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM
lParam)
{
HWND hwndCtl = (HWND)lParam;

Don't use C style casts.

In this case, use a reinterpret_cast or the appropriate system-specific
macro/function (off-topic hint: <windowsx.h>).

Anyway the logic is flawed: you don't yet have enough information to
say that this argument represents what you think it does. But it works.
With a bit of maintainance it will cease to work.

switch(msg)
{
case WM_COMMAND:
switch(wParam)
{
case BN_CLICKED:
if(hwndCtl == hwndButton)
{
strcpy(szMessage,"This program is an overlapped style Window.");

Buffer overflow?

Indentation!

SetWindowText(hwndEdit,szMessage);
}
else if(hwndCtl == hwndClearButton)
{
strcpy(szMessage,"");
SetWindowText(hwndEdit,szMessage);
}
}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
}

return 0;
Unreachable.

}//end MainWndProc()

hello alf,

thank you for your substantive and even-tempered contribution. the
problem appears to have been resolved prior to any replies. i am also
reviewing the specific suggestions you've presented (code-related) for
subsequent use. very relevant.

regards
 
A

August1

Attempt to be gracious noted!
you have certainly misunderstood and presumed many things if you think
that i'm attempting to be gracious.
 
J

John Harrison

August1 said:
you have certainly misunderstood and presumed many things if you think
that i'm attempting to be gracious.

I'm curious what will you do the next time you get a Windows programming
problem? Will you post it here or will you try the other newsgroup I
suggested? Or will you take it somewhere completely different?

I must agree, I didn't think your last post demonstrated any graciousness
either. Phlip was being most presumptuous. My presumption is that you are
one of those people whose vanity or arrogance prevents you from ever
admitting that you've made a mistake.

john
 
R

Randy Yates

John Harrison said:
I'm curious what will you do the next time you get a Windows programming
problem? Will you post it here or will you try the other newsgroup I
suggested? Or will you take it somewhere completely different?

I must agree, I didn't think your last post demonstrated any graciousness
either. Phlip was being most presumptuous. My presumption is that you are
one of those people whose vanity or arrogance prevents you from ever
admitting that you've made a mistake.

john

To be brutally honest, John, I think he (or she) is just stupid. No use
reasoning with a moron.
--
% Randy Yates % "My Shangri-la has gone away, fading like
%% Fuquay-Varina, NC % the Beatles on 'Hey Jude'"
%%% 919-577-9882 %
%%%% <[email protected]> % 'Shangri-La', *A New World Record*, ELO
http://home.earthlink.net/~yatescr
 
R

Raymond Martineau

Don't use global variables.

You might want to suggest an alternative, such as recommending either a
vector for storing HWNDs, a singleton class, or a function that returns a
constant reference to the variable. Alternativly, you could recommend that
the variable be renamed (as it conflicts or is confused with standard
naming conventions with these callback functions) and placed within it's
minimal scope.

There might be cases where variables actually need to be global. For
example, copy protection module might want to give direct global read
access to a set of variables containing a registration key to make it
slightly harder for crackers to disable a centralized copy protection
function. However, this does have a disadvantage of both redundant code and
bugs that appear in the remote functions, but the decision is up to the
designer.
A simpler way might be to use an initializer, "WNDCLASS wc = { ... };".

This requires actually looking at the header file to see which order the
values are assigned. I've seen structures like this before - it's
generally more readable when assigning each member by name, and less prone
to transposition errors. (e.g. switching around fields lpszMenuName and
lpszClassName).
Anyway, to ensure all non-assigned fields are zero, declare it like


WNDCLASS wc = {0};

While you could use that method of using a "clean" structure, it's better
to assign the fields individually to see if "you missed something". While
this not normally be critical, a bug involving core windows messages or
window classes can potentially mess up the system.

It may be a bit better to instead call a function that fills in suitable
default values for the Window Class (with parameters to address the most
common changes), and to make changes as necessairy.
 
D

Default User

E. Robert Tisdale said:
Please ignore our trolls.
They seem to think that it's fun to ambush new subscribers.


I see you still haven't figured out how to use your own killfile there
Trollsdale.




Brian
 
C

Christopher Benson-Manica

Phlip said:
August1, only an elite minority are capable of answering technical
questions, on fora of _their_ choice, and you are danged lucky to have such
a wide selection of them. However, posting to the narrowest technical
newsgroup possible is
==> in your best interest. <==
If, for example, you post a Linux question to a Microsoft newsgroup, you
very well might get a good answer, and a hearty discussion. If you instead
post to a Linux newsgroup, the regulars there will _compete_ with each other
to provide the best answer. They will review each others' answers, provide
emmendments and additions, and generally aid the Linux cause.

This text would be an excellent addition to the welcome messages I and
others link to from time to time (if the maintainers of those
messages are listening to my humble opinion, of course).
 
A

August1

I'm curious what will you do the next time you get a Windows programming
problem? Will you post it here or will you try the other newsgroup I
suggested? Or will you take it somewhere completely different?

I must agree, I didn't think your last post demonstrated any graciousness
either. Phlip was being most presumptuous. My presumption is that you are
one of those people whose vanity or arrogance prevents you from ever
admitting that you've made a mistake.

john

I don't give it much consideration because there are simply too many
resources to derive from, a newsgroup is an infrequent selection, and
your presumption is misguided however well-intended. If the posts are
reviewed, it could be suggested that the latter characterizations
you've offered pertain to others.

regards
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,794
Messages
2,569,641
Members
45,355
Latest member
SJLChristi

Latest Threads

Top