10 Replies - 1701 Views - Last Post: 27 November 2013 - 12:29 AM Rate Topic: -----

#1 DxnadxC   User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 37
  • Joined: 23-July 12

C++ for Windows

Posted 26 November 2013 - 01:18 AM

Hi,
I recently started to code Windows applications using C++, and am having a bit of trouble. When i try to open a folder/dialog box, it only opens once i close the program. My code so far is:
#ifndef UNICODE
#define UNICODE
#endif

#include <windows.h>
#include <ShObjIdl.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{

const wchar_t CLASS_NAME[] = L"Sample Window Class";

WNDCLASS wc = { };

wc.lpfnWndProc   = WindowProc;
wc.hInstance     = hInstance;
wc.lpszClassName = CLASS_NAME;

RegisterClass(&wc);

HWND hwnd = CreateWindowEx
	(
	0,
	CLASS_NAME,
	L"Windows Sample",
	WS_OVERLAPPEDWINDOW,

	CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

	NULL,
	NULL,
	hInstance,
	NULL
	);

if (hwnd == NULL)
{
	return 0;
}

ShowWindow(hwnd, nCmdShow);

MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
	TranslateMessage(&msg);
	DispatchMessage(&msg);
}

	HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | 
        COINIT_DISABLE_OLE1DDE);
    if (SUCCEEDED(hr))
    {
        IFileOpenDialog *pFileOpen;

        hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, 
                IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));

        if (SUCCEEDED(hr))
        {
            hr = pFileOpen->Show(NULL);

            if (SUCCEEDED(hr))
            {
                IShellItem *pItem;
                hr = pFileOpen->GetResult(&pItem);
                if (SUCCEEDED(hr))
                {
                    PWSTR pszFilePath;
                    hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);

                    if (SUCCEEDED(hr))
                    {
                        MessageBox(NULL, pszFilePath, L"File Path", MB_OK);
                        CoTaskMemFree(pszFilePath);
                    }
                    pItem->Release();
                }
            }
            pFileOpen->Release();
        }
        CoUninitialize();
    }
return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

	switch (uMsg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	case WM_PAINT:
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);

			FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
			EndPaint(hwnd, &ps);
		}
		return 0;
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

Thanks for any help
-DxandxC-

Is This A Good Question/Topic? 0
  • +

Replies To: C++ for Windows

#2 boxed   User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 06-November 13

Re: C++ for Windows

Posted 26 November 2013 - 01:56 AM

As a forewarning, it's been a while since I've done any windows projects in c++, but your main loop:
while (GetMessage(&msg, NULL, 0, 0))
{
	TranslateMessage(&msg);
	DispatchMessage(&msg);
}


runs until the user closes the window. So once the close message is received, the loop breaks and continues with the rest of the code. You should have the file open dialog in a function on it's own, and call it from the WindowProc after receiving some message. Give this a try:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

	switch (uMsg)
	{
	case WM_LBUTTONDOWN:
		HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | 
		        COINIT_DISABLE_OLE1DDE);
		    if (SUCCEEDED(hr))
		    {
		        IFileOpenDialog *pFileOpen;

		        hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, 
		                IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));

		        if (SUCCEEDED(hr))
		        {
		            hr = pFileOpen->Show(NULL);

		            if (SUCCEEDED(hr))
		            {
		                IShellItem *pItem;
		                hr = pFileOpen->GetResult(&pItem);
		                if (SUCCEEDED(hr))
		                {
		                    PWSTR pszFilePath;
		                    hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);

		                    if (SUCCEEDED(hr))
		                    {
		                        MessageBox(NULL, pszFilePath, L"File Path", MB_OK);
		                        CoTaskMemFree(pszFilePath);
		                    }
		                    pItem->Release();
		                }
		            }
		            pFileOpen->Release();
		        }
		        CoUninitialize();
		    }
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	case WM_PAINT:
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);

			FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
			EndPaint(hwnd, &ps);
		}
		return 0;
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}



In the above, we're catching the left mouse button message event (WM_LBUTTONDOWN) and using that to bring up the file dialog. When you left click on the form, it should run this code and do what you want it to.

Btw, remember how I said it should be in a function on it's own? I didn't do that, but as you can see your WindowProc can get messy really quick.
Was This Post Helpful? 1
  • +
  • -

#3 DxnadxC   User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 37
  • Joined: 23-July 12

Re: C++ for Windows

Posted 26 November 2013 - 03:26 PM

Hi,
Thanks that looks like it should work, but I'm getting an error:
c:\users\daniel\documents\visual studio 2010\projects\windows tutorial\windows tutorial\window1.cpp(53): error C2601: 'WindowProc' : local function definitions are illegal

With line 53 being line 2:
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

It says that it was expecting a ; when I hover over the open brace. I'm not really sure how to fix this, as I'm new to Windows.
Thnaks
-DxnadxC-

This post has been edited by DxnadxC: 26 November 2013 - 03:27 PM

Was This Post Helpful? 0
  • +
  • -

#4 gaurav ujjwal   User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 16
  • Joined: 22-November 13

Re: C++ for Windows

Posted 26 November 2013 - 09:56 PM

Hi..

You should enclose the whole code for message

case WM_LBUTTONDOWN:


in '{}'

because whenever you need to declare variables inside the case: statement you have to
enclose them in '{}'
This seems to be your problem.
Hope it works..
Was This Post Helpful? 1
  • +
  • -

#5 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7139
  • View blog
  • Posts: 24,245
  • Joined: 05-May 12

Re: C++ for Windows

Posted 26 November 2013 - 11:21 PM

Post your newly modified code. It's hard to guess at what edits you made.
Was This Post Helpful? 0
  • +
  • -

#6 gaurav ujjwal   User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 16
  • Joined: 22-November 13

Re: C++ for Windows

Posted 27 November 2013 - 12:09 AM

modified code


#ifndef UNICODE
#define UNICODE
#endif

#include <windows.h>
#include <ShObjIdl.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{

const wchar_t CLASS_NAME[] = L"Sample Window Class";

WNDCLASS wc = { };

wc.lpfnWndProc   = WindowProc;
wc.hInstance     = hInstance;
wc.lpszClassName = CLASS_NAME;

RegisterClass(&wc);

HWND hwnd = CreateWindowEx
	(
	0,
	CLASS_NAME,
	L"Windows Sample",
	WS_OVERLAPPEDWINDOW,

	CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

	NULL,
	NULL,
	hInstance,
	NULL
	);

if (hwnd == NULL)
{
	return 0;
}

ShowWindow(hwnd, nCmdShow);

MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
	TranslateMessage(&msg);
	DispatchMessage(&msg);
}

return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

	switch (uMsg)
	{
	case WM_LBUTTONDOWN:/* I made following changes changes */
                          /*  put a opening bracket  here to be able to declare variables in a case statement*/
                                       
                      {        /* opening bracket  */         
         
		                HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | 
		                COINIT_DISABLE_OLE1DDE);
		                if (SUCCEEDED(hr))
		                {
		                  IFileOpenDialog *pFileOpen;

		                  hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, 
		                  IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));

		                  if (SUCCEEDED(hr))
		                  {
		                   hr = pFileOpen->Show(NULL);

		                    if (SUCCEEDED(hr))
		                    {
		                      IShellItem *pItem;
		                      hr = pFileOpen->GetResult(&pItem);
		                      if (SUCCEEDED(hr))
		                      {
		                        PWSTR pszFilePath;
		                        hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);

		                        if (SUCCEEDED(hr))
		                        {
		                           MessageBox(NULL, pszFilePath, L"File Path", MB_OK);
		                           CoTaskMemFree(pszFilePath);
		                        }
		                      pItem->Release();
		                   }
		                }
		               pFileOpen->Release();
		              }
		            CoUninitialize();
		          }
               } /*     Here is my closing bracket   */
                
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	case WM_PAINT:
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);

			FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
			EndPaint(hwnd, &ps);
		}
		return 0;
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}




and it work....

modified code


#ifndef UNICODE
#define UNICODE
#endif

#include <windows.h>
#include <ShObjIdl.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{

const wchar_t CLASS_NAME[] = L"Sample Window Class";

WNDCLASS wc = { };

wc.lpfnWndProc   = WindowProc;
wc.hInstance     = hInstance;
wc.lpszClassName = CLASS_NAME;

RegisterClass(&wc);

HWND hwnd = CreateWindowEx
	(
	0,
	CLASS_NAME,
	L"Windows Sample",
	WS_OVERLAPPEDWINDOW,

	CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

	NULL,
	NULL,
	hInstance,
	NULL
	);

if (hwnd == NULL)
{
	return 0;
}

ShowWindow(hwnd, nCmdShow);

MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
	TranslateMessage(&msg);
	DispatchMessage(&msg);
}

return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

	switch (uMsg)
	{
	case WM_LBUTTONDOWN:/* I made following changes changes */
                          /*  put a opening bracket  here to be able to declare variables in a case statement*/
                                       
                      {        /* opening bracket  */         
         
		                HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | 
		                COINIT_DISABLE_OLE1DDE);
		                if (SUCCEEDED(hr))
		                {
		                  IFileOpenDialog *pFileOpen;

		                  hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, 
		                  IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));

		                  if (SUCCEEDED(hr))
		                  {
		                   hr = pFileOpen->Show(NULL);

		                    if (SUCCEEDED(hr))
		                    {
		                      IShellItem *pItem;
		                      hr = pFileOpen->GetResult(&pItem);
		                      if (SUCCEEDED(hr))
		                      {
		                        PWSTR pszFilePath;
		                        hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);

		                        if (SUCCEEDED(hr))
		                        {
		                           MessageBox(NULL, pszFilePath, L"File Path", MB_OK);
		                           CoTaskMemFree(pszFilePath);
		                        }
		                      pItem->Release();
		                   }
		                }
		               pFileOpen->Release();
		              }
		            CoUninitialize();
		          }
               } /*     Here is my closing bracket   */
                
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	case WM_PAINT:
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);

			FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
			EndPaint(hwnd, &ps);
		}
		return 0;
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}




and it works....
Was This Post Helpful? 1
  • +
  • -

#7 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7139
  • View blog
  • Posts: 24,245
  • Joined: 05-May 12

Re: C++ for Windows

Posted 27 November 2013 - 12:13 AM

So you are not getting the error about local function definition anymore?
Was This Post Helpful? 0
  • +
  • -

#8 gaurav ujjwal   User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 16
  • Joined: 22-November 13

Re: C++ for Windows

Posted 27 November 2013 - 12:16 AM

I am realy sorry...
by mistake it posted twice...

sory......:-(
Was This Post Helpful? 0
  • +
  • -

#9 DxnadxC   User is offline

  • New D.I.C Head

Reputation: 3
  • View blog
  • Posts: 37
  • Joined: 23-July 12

Re: C++ for Windows

Posted 27 November 2013 - 12:19 AM

Thanks to all that helped, especially to gaurav ujjwal, as your solution fixed the problem and also explained why. One other thing though, is there a way to open a specific folder instead of just my documents??
-DxandxC-
Was This Post Helpful? 0
  • +
  • -

#10 gaurav ujjwal   User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 16
  • Joined: 22-November 13

Re: C++ for Windows

Posted 27 November 2013 - 12:20 AM

YES
it runs fine with visual c++ 2010
Was This Post Helpful? 0
  • +
  • -

#11 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7139
  • View blog
  • Posts: 24,245
  • Joined: 05-May 12

Re: C++ for Windows

Posted 27 November 2013 - 12:29 AM

Yes, you can, but the MSDN recommendation recommends against it. Read more about IFileDialog::SetFolder().
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1