WinAPI - Window creation - Incorrect window size

Hi!

I was trying to create two windows using WinAPI. I created a window wrapper class, which seems to work alright, handling window registeration and creation.

"Functionality executes fast, everything works fine... But hey, wait a minute! What's up with the window size!?"

That's what I though when I saw my two windows pop up. No, the windows didn't have wierd look and no, their position wasn't incorrect, but the size... yeah... ...it was all wrong.

OK, enough literature. To put it bluntly, window size was like "squared". I can't find words effective enough to describe it short, but an example would be nice - right?

So, I gave my first width 800 in pixels and height 600 in pixels. However, it turns out these values have somehow magically changed to 700, an average of these two values. What!? Why!?

Do you know the answer? For me, this is just plain stupid. How did this happen? What's going on?
Last edited on
You're not specifying the size you think you are. If you tell it to make a window that is 800x600, that's what it'll do.

double-check the following:

1) Put a breakpoint on your window creation code (or wherever you're specifying the size of your window) and make sure you are in fact giving it 800x600.

2) Take a snapshot of the window (alt+printscreen as its running), paste it into paint, and see if the dimensions are in fact 800x600
Thanks for your suggestions, Disch, but I've already used the GetWindowRect-function to get window size.

An example is always nice, so here's a part of my code (from save_changes-method):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
	::WNDCLASSEX& __wcex = _m_oHandler._m_opWndClassEx;
	__wcex.cbSize			= sizeof(WNDCLASSEX);
	__wcex.style			= NULL;
	__wcex.lpfnWndProc	= __TFW_Window_handle_wnd_proc;
	__wcex.cbClsExtra		= 0;
	__wcex.cbWndExtra	= DLGWINDOWEXTRA;
	__wcex.hInstance		= _m_oHandler._m_opHandlerInstance;
	__wcex.hIcon			= NULL;
	__wcex.hCursor		= ::LoadCursor(NULL, IDC_ARROW);
	__wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW);
	__wcex.lpszMenuName	= 0;
	__wcex.lpszClassName	= _m_cpName;
	__wcex.hIconSm		= 0;

	if(!::RegisterClassEx(&__wcex))
#	ifdef __TFW_COMPILATION_SETTING_ENBALED_EXCEPTIONS__
		throw "[WINDOWS] : Window registration failed.";
#	else
		return;
#	endif /** __TFW_COMPILATION_SETTING_ENBALED_EXCEPTIONS__ **/
	_m_oHandler._m_opHandlerWindow = ::CreateWindowEx(
		WS_EX_CLIENTEDGE,
		__wcex.lpszClassName, _m_cpName,
		WS_OVERLAPPEDWINDOW | WS_VISIBLE,
		(_m_bSetPosition) ? _m_uiPos[0] : CW_USEDEFAULT, (_m_bSetPosition) ? _m_uiPos[1] : CW_USEDEFAULT,
		_m_uiSize[0], _m_uiSize[1],
		NULL, NULL, _m_oHandler._m_opHandlerInstance, NULL
	);
Last edited on
Are you sure _m_uiSize[0] == 800 and _m_uiSize[1] == 600 there? Have you set a breakpoint and looked at the memory?

Try this:
1
2
3
4
5
6
7
8
9
_m_oHandler._m_opHandlerWindow = ::CreateWindowEx(  ...  );

RECT rc;
::GetWindowRect( _m_oHandler._m_opHandlerWindow, &rc );

if( ((rc.right - rc.left) != _m_uiSize[0]) || ((rc.bottom - rc.top) != _m_uiSize[1]) )
{
  // .. this code should not execute
}


If that if-block DOES execute, I'd be very, very surprised. Try it and let me know.
Thanks, Disch. I tried it and it worked fine (fortunately), but I still can't understand why the window sizes are incorrect...
Are they?

Unless you are resizing the window later, that above code should have just proved they are sized correctly.

Another thing you can try is put the GetWindowRect confirmation somewhere where it can be triggered. So after you see the window, when you press 'space' or something, check the window size again and confirm it is still correct.

If it's correct, it's your eyes playing tricks on you.
If it's incorrect, you are resizing the window somewhere, and that's what you need to find and fix.
On the off chance that this is the case.. Henri, are you sizing the window with the expectation of the client window being 800x600? If that's the case the window size is based on the entire window, not the client window.
I'm sorry, Ikaron, but I don't understand. Could you please elaborate?
Last edited on
The client window is the space within the border of your entire window. When you create a window and give it a width and height, this includes the border, title bar, etc. not just the space within the border.
What would you suggest me to do?
OK, this works:
1
2
3
4
5
6
7
8
9
_m_oHandler._m_opHandlerWindow = ::CreateWindowEx(
		WS_EX_CLIENTEDGE,
		__wcex.lpszClassName, _m_cpName,
		WS_OVERLAPPEDWINDOW | WS_VISIBLE,
		(_m_bSetPosition) ? _m_uiPos[0] : CW_USEDEFAULT,
		(_m_bSetPosition) ? _m_uiPos[1] : CW_USEDEFAULT,
		800, 600,
		NULL, NULL, _m_oHandler._m_opHandlerInstance, NULL
	);


And this one doesn't:
1
2
3
4
5
6
7
8
9
_m_oHandler._m_opHandlerWindow = ::CreateWindowEx(
		WS_EX_CLIENTEDGE,
		__wcex.lpszClassName, _m_cpName,
		WS_OVERLAPPEDWINDOW | WS_VISIBLE,
		(_m_bSetPosition) ? _m_uiPos[0] : CW_USEDEFAULT,
		(_m_bSetPosition) ? _m_uiPos[1] : CW_USEDEFAULT,
		_m_uiSize[0], _m_uiSize[1],
		NULL, NULL, _m_oHandler._m_opHandlerInstance, NULL
	);


???
There's a function called GetClientRect which returns the current size of the client window. You can use that with GetWindowRect to re-adjust the window size accordingly after it's been created. I can give you a function that does this but will only do so if you ask for it incase you'd rather do the problem solving yourself.

Edit:
Looks like the issue is more likely to be what Disch pointed out. Are you absolutely sure that _m_uiSize[0] == 800, and _m_uiSize[1] == 600 ?
Last edited on
Thanks, Ikaron. The sizes of these two windows are valid.

I can't figure this out. Could you help me out?
Can't be of that much help without knowing how defining _m_uiSize is handled.
Last edited on
OK, here's my main-function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main(int argc, char** argv){
	TFW::Window window("Tim Editor", {800, 600});
	TFW::Window window2("Tim Editor2");

	window.set_position({100, 100});
	window.save_changes();

	window2.set_position({100, 100});
	window2.set_size({640, 480});
	window2.save_changes();

    while(window.is_enabled())
        window.display();
    while(window2.is_enabled())
        window2.display();

    return 0;
}


And here's my Component -base class' set_size-method:

1
2
3
4
Component& Component::set_size(std::initializer_list<uint_t> const size){
	_m_uiSize = __TFW_Component_to_array(size, _m_uiSize);
	return *this;
}


As you can see, I'm using std::initializer_list-class.

And here's the initialization list "unpacker" function:
1
2
3
4
5
6
inline std::array<uint_t, 2>& __TFW_Component_to_array(std::initializer_list<uint_t> const& list, std::array<uint_t, 2>& array){
	auto __i = list.begin();
	array[0] = *(++__i);
	array[1] = *__i;
	return array;
}

1
2
3
4
5
6
inline std::array<uint_t, 2>& __TFW_Component_to_array(std::initializer_list<uint_t> const& list, std::array<uint_t, 2>& array){
	auto __i = list.begin();
	array[0] = *(++__i);
	array[1] = *__i;
	return array;
}


You're skiping the first element.
array[0] is being set to 600
array[1] is being set to out of bounds garbage

You probably meant to do this:

1
2
3
4
5
6
inline std::array<uint_t, 2>& __TFW_Component_to_array(std::initializer_list<uint_t> const& list, std::array<uint_t, 2>& array){
	auto __i = list.begin();
	array[0] = *(__i++);  // <- note, postfix, not prefix
	array[1] = *__i;
	return array;
}



Serves you right for compounding statements like that ;P (j/k of course)


EDIT:

Also.. don't want to sound like a "told you so"....

I in my first reply wrote:

double-check the following:

1) Put a breakpoint on your window creation code (or wherever you're specifying the size of your window) and make sure you are in fact giving it 800x600.


Had you done this at the start, you would have seen you weren't passing 800 and 600 like you thought, and would have found the problem sooner.
Last edited on
Thank you, Disch! I was already aware of this prefix and posfix feature of decreasement and increasement operator and what's the difference between the two, so I'm surprised I didn't notice that kind of mistake in my code. Thanks for pointing it out, Disch!

Thank you for you, too, Ikaron!

Thank you all for your patience and support!
Topic archived. No new replies allowed.