WinAPI Combo Box wont show

Started by
16 comments, last by MystikReasons 7 years, 4 months ago
It's a bit difficult to see with out of context snippets of code but you seem to instantiate your m_combobox before you even register and create you main window.
Advertisement

@Fredericvo

I move the instantiate now after I register and create the main window, but it still doesn't work.

Heres the code for the core functions.


HRESULT wWindow::Initialize()
{
	HRESULT hr;

	// Create the window class.
	WNDCLASSEX wcex    = { sizeof(WNDCLASSEX) };

	wcex.style         = CS_HREDRAW | CS_VREDRAW;		// The class styles - CS_HREDRAW: Redraws the window if a movement changes the width of the client area.
														// CS_VREDRAW: Redraws the window if a movement changes the height of the client area.

	wcex.lpfnWndProc   = wWindow::WndProc;				// A pointer to the windows procedure.
	wcex.cbClsExtra	   = 0;								// The number of extra bytes to allocate the window-class structure.
	wcex.cbWndExtra    = sizeof(LONG_PTR);				// The number of extra bytes to allocate following the window instance.
	wcex.hInstance     = HINST_THISCOMPONENT;			// A handle to the instance that contains the window procedure for the class.
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);	// A handle to the class background brush.
	wcex.lpszMenuName  = NULL;							// Pointer to a null-terminated character string that specifies the resource name of the class menu.
	wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);	// A handle to the class cursor, contains the cursor for the window.
	wcex.lpszClassName = TEXT("DemoApp");				// The name of the class

	// Register the window class.
	RegisterClassEx(&wcex);

	// Create the application window.
	//
	// Because the CreateWindow function takes its size in pixels, we
	// obtain the system DPI and use it to scale the window size.
	int dpiX = 0;
	int dpiY = 0;
	HDC hdc = GetDC(NULL);

	if (hdc)
	{
		dpiX = GetDeviceCaps(hdc, LOGPIXELSX);	// Get the pixels from width
		dpiY = GetDeviceCaps(hdc, LOGPIXELSY);	// Get the pixels from height
		ReleaseDC(NULL, hdc);
	}

	// Create the window
	m_hwnd = CreateWindow(TEXT("DemoApp"),								// Class name.
						  TEXT("CircuitSim"),							// Window name.
						  WS_OVERLAPPEDWINDOW |WS_HSCROLL | WS_VSCROLL,							// Window style - WS_OVERLAPPEDWINDOW: The window is an overlapped window.
						  CW_USEDEFAULT,								// Use the default x position.
						  CW_USEDEFAULT,								// Use the default y position.
						  static_cast<UINT>(ceil(640.f * dpiX / 96.f)),	// Use the width, which we calculated with the pixels.
						  static_cast<UINT>(ceil(480.f * dpiY / 96.f)),	// Use the height, which we calculated with the pixels.
						  NULL,											// A handle to the parent window
						  NULL,											// A handle to a menu
						  HINST_THISCOMPONENT,							// A handle to the instance of the module
						  this);										// A pointer to a value to be passed to the window through the CREATESTRUCT structure

	ComboBox m_comboBox;	// Create a instance for ComboBox
							// Initialize all the combo boxes here

	// Check if the window passed the following checks - S_OK: Operation sucessful
	//													 E_FAIL: Unspecified failure
	hr = m_hwnd ? S_OK : E_FAIL;
	if (SUCCEEDED(hr))
	{
		ShowWindow(m_hwnd, SW_MAXIMIZE);	// Show the window - SW_MAXIMIZE: set the window to fullscreen
		UpdateWindow(m_hwnd);
	}
	
	return hr;
}


LRESULT CALLBACK wWindow::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	LRESULT result = 0;

	if (message == WM_CREATE)
	{
		LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
		wWindow *pWindow = (wWindow *)pcs->lpCreateParams;

		::SetWindowLongPtrW(
			hwnd,
			GWLP_USERDATA,
			PtrToUlong(pWindow)
		);

		result = 1;
	}
	else
	{
		wWindow *pWindow = reinterpret_cast<wWindow *>(static_cast<LONG_PTR>(
			::GetWindowLongPtrW(
				hwnd,
				GWLP_USERDATA)));

		bool wasHandled = false;

		if (pWindow)
		{
			switch (message)
			{
				case WM_COMMAND:
				{
					// If the user makes a selection from the list:
					//   Send CB_GETCURSEL message to get the index of the selected list item.
					//   Send CB_GETLBTEXT message to get the item.
					//   Display the item in a messagebox.
					if (HIWORD(wParam) == CBN_SELCHANGE)
					{
						int ItemIndex = SendMessage((HWND)lParam, (UINT)CB_GETCURSEL,
												   (WPARAM)0, (LPARAM)0);

						TCHAR  ListItem[256];

						(TCHAR)SendMessage((HWND)lParam,
										  (UINT)CB_GETLBTEXT,
										  (WPARAM)ItemIndex,
										  (LPARAM)ListItem);
						 
						// TODO:
						// Do something after that
					}

					wasHandled = true;
					result = 0;
				} break;

				// The WM_DISPLAYCHANGE message is sent to all windows when the display resolution has changed.
				case WM_DISPLAYCHANGE:
				{		
					InvalidateRect(hwnd, NULL, FALSE);
				} 
				wasHandled = true;
				result = 0;
				break;

				// Destroy the window
				case WM_DESTROY:
				{
					PostQuitMessage(0);
				} 		
				wasHandled = true;
				result = 1;
				break;
			}
		}

		if (!wasHandled)
		{
			result = DefWindowProc(hwnd, message, wParam, lParam);
		}
	}

	return result;
}

void ComboBox::Initialize()
{
	wWindow wWindow;	// Create a instance of wWindow class

	////////////////////////////////////
	//								  //
	//		Combobox Informations	  //
	//								  //    
	////////////////////////////////////	
	TCHAR Combobox_File[7][13] =
	{
		TEXT("New"), TEXT("Open"), TEXT("Add"), TEXT("Save		Ctrl+S"),
		TEXT("Save As..."), TEXT("Save All"), TEXT("Exit		Alt+F4")
	};
 
	// Create the parameters for FILE Combobox
	//
	// Uses the CreateWindow function to create a child window of 
	// the application window. The WC_COMBOBOX window style specifies  
	// that it is a combobox.
	int xPos = 100;					// Horizontal position of the window
	int yPos = 100;					// Vertical position of the window
	int nWidth = 200;				// Width of the window
	int nHeight = 200;				// Height of the window
	hWndParent = wWindow.getHwnd();	// Get the window from the Window Class

	// Create the Combobox_File
	hWndComboBox_File = CreateWindow(WC_COMBOBOX, TEXT(""),
										  CBS_DROPDOWN |
										  CBS_HASSTRINGS |
										  WS_CHILD |
										  WS_VISIBLE,
										  xPos,
										  yPos,
										  nWidth,
										  nHeight,
										  hWndParent,
										  NULL,
										  HINST_THISCOMPONENT,
										  NULL);

	TCHAR A[17];
	int k = 0;

	memset(&A, 0, sizeof(A));
	// Go trough every TEXT in the string
	for (k = 0; k <= 8; k += 1)
	{
		// Copies a string
		_tcscpy_s(A, sizeof(A) / sizeof(TCHAR), (TCHAR*)Combobox_File[k]);

		// Add string to combobox
		SendMessage(hWndComboBox_File, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)A);
	}

	// Send the CB_SETCURSEL message to display an initial item 
	// in the selection field  
	SendMessage(hWndComboBox_File, CB_SETCURSEL, (WPARAM)2, (LPARAM)0);

	return;
}

int WINAPI WinMain(
	HINSTANCE     /* hInstance */,
	HINSTANCE     /* hPrevInstance */,
	LPSTR     /* lpCmdLine */,
	int)     /* nCmdShow */
{
	 
	HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
	if (SUCCEEDED(CoInitialize(NULL)))
	{
		{
			wWindow app;

			if (SUCCEEDED(app.Initialize()))
			{
				app.RunMessageLoop();
			}
		}
		CoUninitialize();
	}
	return 0;
}


I get an error from GetLastError, saved it in an txt. file

What does this error mean to my problem?

ERROR_ALREADY_EXISTS

Cannot create a file when that file already exists.

183 (0xB7)

I get an error from GetLastError, saved it in an txt. file
What does this error mean to my problem?



ERROR_ALREADY_EXISTS

Cannot create a file when that file already exists.

183 (0xB7)



It literally means what it means and seems unrelated to your problem. Are you using CreateFileEx somewhere in your code? If CreateWindowEx succeeds it's not going to "reset" the error value.
http://microsoft.public.win32.programmer.ui.narkive.com/OamvbzgN/createwindowex-returns-error-already-exists
Does your ComboBox class destroy the handle in its destructor?

In your wWindow::Initialize you create a local ComboBox instance, which is destroyed when the function is left.



Also, in your ComboBox::Initialize you create a local wWindow instance, which obviously has no connection to the main app window. Therefore your parent HWND is NULL.

What does the debugger say? Is

hWndComboBox_File = CreateWindow...

actually setting a value not equil NULL to hWndComboBox_File ?

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

It literally means what it means and seems unrelated to your problem. Are you using CreateFileEx somewhere in your code? If CreateWindowEx succeeds it's not going to "reset" the error value.
http://microsoft.public.win32.programmer.ui.narkive.com/OamvbzgN/createwindowex-returns-error-already-exists

Thank you for that useful information.

Does your ComboBox class destroy the handle in its destructor?

In your wWindow::Initialize you create a local ComboBox instance, which is destroyed when the function is left.



Also, in your ComboBox::Initialize you create a local wWindow instance, which obviously has no connection to the main app window. Therefore your parent HWND is NULL.

What does the debugger say? Is

hWndComboBox_File = CreateWindow...

actually setting a value not equil NULL to hWndComboBox_File ?

The debugger says, that the hWndComboBox_File NULL is.

Yes I'm creating a wWindow instance, which I used to get the hWnd but the instance is also deleting itself, because its on the stack.


hWndParent = wWindow.getHwnd();	// Get the window from the Window Class

Could this be the error?

Trying to create a child window (WS_CHILD) with parent HWND set to NULL fails IIRC.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Trying to create a child window (WS_CHILD) with parent HWND set to NULL fails IIRC.

You are absolutly right, it works now but not how as I wanted but anyways thank you :D

I'll try to fix the other problem tomorrow :)

This topic is closed to new replies.

Advertisement