CDialogEventHandler_CreateInstance Identifier Not Found
Asked Answered
S

4

8

I have been following several guides/examples on creating a Vista/7 open file dialog box and have now hit a dead end due to an error message stating that main.cpp(189): error C3861: 'CDialogEventHandler_CreateInstance': identifier not found.

I could find nothing about this on Google except for one page where someone rewrote the sample code to not use the CDialogEventHandler class.

Here is my code. The CDialogEventHandler class and function definitions come straight from the Windows 7 SDK sample for the CommonFileDialogApp:

#include "resource.h"

#include <windows.h>      // For common windows data types and function headers
#define STRICT_TYPED_ITEMIDS
#include <objbase.h>      // For COM headers
#include <shobjidl.h>     // for IFileDialogEvents and IFileDialogControlEvents
#include <shlwapi.h>
#include <knownfolders.h> // for KnownFolder APIs/datatypes/function headers
#include <propvarutil.h>  // for PROPVAR-related functions
#include <propkey.h>      // for the Property key APIs/datatypes
#include <propidl.h>      // for the Property System APIs
#include <strsafe.h>      // for StringCchPrintfW
#include <shtypes.h>      // for COMDLG_FILTERSPEC
#include <new>

// Controls
#define CONTROL_GROUP           2000
#define CONTROL_RADIOBUTTONLIST 2
#define CONTROL_RADIOBUTTON1    1
#define CONTROL_RADIOBUTTON2    2       // It is OK for this to have the same IDas     CONTROL_RADIOBUTTONLIST,
                                        // because it is a child control under CONTROL_RADIOBUTTONLIST

// IDs for the Task Dialog Buttons
#define IDC_BASICFILEOPEN                       100
#define IDC_ADDITEMSTOCUSTOMPLACES              101
#define IDC_ADDCUSTOMCONTROLS                   102
#define IDC_SETDEFAULTVALUESFORPROPERTIES       103
#define IDC_WRITEPROPERTIESUSINGHANDLERS        104
#define IDC_WRITEPROPERTIESWITHOUTUSINGHANDLERS 105

HWND ghMainWnd = 0;
HINSTANCE ghAppInst = 0;
RECT winRect;

void centerWnd(HWND parent_window);
void openDB();

class CDialogEventHandler : public IFileDialogEvents,
                            public IFileDialogControlEvents
{
public:
    // IUnknown methods
    IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv)
    {
        static const QITAB qit[] = {
            QITABENT(CDialogEventHandler, IFileDialogEvents),
            QITABENT(CDialogEventHandler, IFileDialogControlEvents),
            { 0 },
        };
        return QISearch(this, qit, riid, ppv);
    }

    IFACEMETHODIMP_(ULONG) AddRef()
    {
        return InterlockedIncrement(&_cRef);
    }

    IFACEMETHODIMP_(ULONG) Release()
    {
        long cRef = InterlockedDecrement(&_cRef);
        if (!cRef)
            delete this;
        return cRef;
    }

    // IFileDialogEvents methods
    IFACEMETHODIMP OnFileOk(IFileDialog *) { return S_OK; };
    IFACEMETHODIMP OnFolderChange(IFileDialog *) { return S_OK; };
    IFACEMETHODIMP OnFolderChanging(IFileDialog *, IShellItem *) { return S_OK; };
    IFACEMETHODIMP OnHelp(IFileDialog *) { return S_OK; };
    IFACEMETHODIMP OnSelectionChange(IFileDialog *) { return S_OK; };
    IFACEMETHODIMP OnShareViolation(IFileDialog *, IShellItem *, FDE_SHAREVIOLATION_RESPONSE *) { return S_OK; };
    IFACEMETHODIMP OnTypeChange(IFileDialog *pfd);
    IFACEMETHODIMP OnOverwrite(IFileDialog *, IShellItem *, FDE_OVERWRITE_RESPONSE *) { return S_OK; };

    // IFileDialogControlEvents methods
    IFACEMETHODIMP OnItemSelected(IFileDialogCustomize *pfdc, DWORD dwIDCtl, DWORD dwIDItem);
    IFACEMETHODIMP OnButtonClicked(IFileDialogCustomize *, DWORD) { return S_OK; };
    IFACEMETHODIMP OnCheckButtonToggled(IFileDialogCustomize *, DWORD, BOOL) { return S_OK; };
    IFACEMETHODIMP OnControlActivating(IFileDialogCustomize *, DWORD) { return S_OK; };

    CDialogEventHandler() : _cRef(1) { };
private:
    ~CDialogEventHandler() { };
    long _cRef;
};

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_COMMAND:
        switch(LOWORD(wParam))
        {
        case ID_FILE_OPENDB:
            openDB();
            break;

        default:
            break;


        }

        break;
    case WM_LBUTTONDOWN:
        MessageBox(0, "WM_LBUTTONDOWN message.", "Msg", MB_OK);
        return 0;

    case WM_KEYDOWN:
        if (wParam == VK_ESCAPE)
            DestroyWindow(ghMainWnd);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR cmdLine, int showCmd)
{
    ghAppInst = hInstance;

    HMENU mMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));

    WNDCLASS wc;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = ghAppInst;
    wc.hIcon = ::LoadIcon(0, IDI_APPLICATION);
    wc.hCursor = ::LoadCursor(0, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) ::GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = 0;
    wc.lpszClassName = "MyWndClassName";

    RegisterClass(&wc);

    centerWnd(GetDesktopWindow());

    ghMainWnd = ::CreateWindow("MyWndClassName", "Space Crusade Database Editor V1.0", WS_OVERLAPPEDWINDOW, winRect.left, winRect.top, 1280, 720, 0, mMenu, ghAppInst, 0);

    if(ghMainWnd == 0)
    {
        ::MessageBox(0, "CreateWindow - Failed", 0, 0);
        return false;
    }

    ShowWindow(ghMainWnd, showCmd);
    UpdateWindow(ghMainWnd);

    MSG msg;
    ZeroMemory(&msg, sizeof(MSG));

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

    return (int)msg.wParam;
}

void centerWnd(HWND parent_window)
{
    GetClientRect(parent_window, &winRect);
    winRect.left = (winRect.right/2) - (1280/2);
    winRect.top = (winRect.bottom/2) - (720/2);
}

void openDB()
{
    //Cocreate the file open dialog object
    IFileDialog *pfd = NULL;

    HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd));

    if (SUCCEEDED(hr))
    {
        //Stuff needed for later
        const COMDLG_FILTERSPEC rgFExt[] = {{L"SQLite3 Database (*.sqlite)", L"*.sqlite"}};
        WCHAR fPath[MAX_PATH] = {};

        //Create event handling
        IFileDialogEvents *pfde = NULL;
        hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde));

        if(SUCCEEDED(hr))
        {
            //Hook the event handler
            DWORD dwCookie;

            hr = pfd->Advise(pfde, &dwCookie);

            if (SUCCEEDED(hr))
            {
                //Set options for the dialog
                DWORD dwFlags;

                //Get options first so we do not override
                hr = pfd->GetOptions(&dwFlags);

                if (SUCCEEDED(hr))
                {
                    //Get shell items only
                    hr = pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM);

                    if (SUCCEEDED(hr))
                    {
                        //Types of files to display (not default)
                        hr = pfd->SetFileTypes(ARRAYSIZE(rgFExt), rgFExt);

                        if (SUCCEEDED(hr))
                        {
                            //Set default file type to display
                            hr = pfd->SetDefaultExtension(L"sqlite");

                            if (SUCCEEDED(hr))
                            {
                                //Show dialog
                                hr = pfd->Show(NULL);

                                if (SUCCEEDED(hr))
                                {
                                    //Get the result once the user clicks on open
                                    IShellItem *result;

                                    hr = pfd->GetResult(&result);

                                    if (SUCCEEDED(hr))
                                    {
                                        //Print out the file name
                                        PWSTR fName = NULL;

                                        hr = result->GetDisplayName(SIGDN_FILESYSPATH, &fName);

                                        if (SUCCEEDED(hr))
                                        {
                                            TaskDialog(NULL,NULL,L"File Name",fName,NULL,TDCBF_OK_BUTTON,TD_INFORMATION_ICON,NULL);
                                            CoTaskMemFree(fName);
                                        }

                                        result->Release();
                                    }
                                }
                            }
                        }
                    }
                }
            }

            pfd->Unadvise(dwCookie);
        }

        pfde->Release();
    }

    pfd->Release();
}


HRESULT CDialogEventHandler_CreateInstance(REFIID riid, void **ppv)
{
    *ppv = NULL;
    CDialogEventHandler *pDialogEventHandler = new (std::nothrow) CDialogEventHandler();
    HRESULT hr = pDialogEventHandler ? S_OK : E_OUTOFMEMORY;
    if (SUCCEEDED(hr))
    {
        hr = pDialogEventHandler->QueryInterface(riid, ppv);
        pDialogEventHandler->Release();
    }
    return hr;
}

HRESULT CDialogEventHandler::OnTypeChange(IFileDialog *pfd)
{
    IFileSaveDialog *pfsd;
    HRESULT hr = pfd->QueryInterface(&pfsd);
    if (SUCCEEDED(hr))
    {
        UINT uIndex;
        hr = pfsd->GetFileTypeIndex(&uIndex);   // index of current file-type
        if (SUCCEEDED(hr))
        {
            IPropertyDescriptionList *pdl = NULL;


        }
        pfsd->Release();
    }
    return hr;
}

// IFileDialogControlEvents
// This method gets called when an dialog control item selection happens (radio-button selection. etc).
// For sample sake, let's react to this event by changing the dialog title.
HRESULT CDialogEventHandler::OnItemSelected(IFileDialogCustomize *pfdc, DWORD dwIDCtl, DWORD dwIDItem)
{
    IFileDialog *pfd = NULL;
    HRESULT hr = pfdc->QueryInterface(&pfd);
    if (SUCCEEDED(hr))
    {
        if (dwIDCtl == CONTROL_RADIOBUTTONLIST)
        {
            switch (dwIDItem)
            {
            case CONTROL_RADIOBUTTON1:
                hr = pfd->SetTitle(L"Longhorn Dialog");
                break;

            case CONTROL_RADIOBUTTON2:
                hr = pfd->SetTitle(L"Vista Dialog");
                break;
            }
        }
        pfd->Release();
    }
    return hr;
}
Spears answered 26/5, 2014 at 2:56 Comment(2)
daniweb.com/software-development/cpp/threads/394132/…Calesta
@Calesta This was the post I mentioned in the OP. I want to use the Microsoft supplied code. I think I found the problem though. Read my Answer for more.Spears
S
1

So I managed to get the code to work. What I did was I took the solution file from the Sample mentioned in the original post and attempted to build and run it. This was successful which lead me to believe that the problem was in the project settings. I tried switching back to Unicode for the typeset but this did not fix the problem.

In the end I just co-opted the Sample project and I am now altering it to me needs. I am not sure what project options are needed to make it work but I am almost sure it has to do with with something in the linker options.

Spears answered 26/5, 2014 at 18:27 Comment(1)
Currently the documentation states that CDialogEventHandler_CreateInstance is not a Windows API function but rather a helper function for which the source code is a part of the example project. This is why you were able to use it when you commandeered the sample project, it's just defined in one of the source files and you didn't notice.Chlorpromazine
R
1

Not sure you have got the entire sample code, try github sample below with these libraries, should compile first time.

//Libraries I added to get this to work.
#pragma comment(lib,"comctl32.lib") 
#pragma comment(lib,"propsys.lib")
#pragma comment(lib,"shlwapi.lib") 

https://github.com/pauldotknopf/WindowsSDK7-Samples/blob/master/winui/shell/appplatform/commonfiledialog/CommonFileDialogApp.cpp

Redress answered 9/8, 2019 at 6:54 Comment(2)
Please explain it a bit.Subordinary
The code sample provided, works today 9/8/19 with windows 10. Make a new Visual Studio 2017(tested on), win32 cpp project. Replace the default project code, eg WindowsProject4.cpp, with the sample code from github link. Add in the libraries provided above into the code in the pragma comment section. Compile, tested and works for me.Redress
C
0

CDialogEventHandler_CreateInstance is a helper function defined in Microsoft's CommonFileDialogue example app. You can also find the GitHub page from the MSDN page.

HRESULT CDialogEventHandler_CreateInstance(REFIID riid, void **ppv)
{
    *ppv = NULL;
    CDialogEventHandler *pDialogEventHandler = new (std::nothrow) CDialogEventHandler();
    HRESULT hr = pDialogEventHandler ? S_OK : E_OUTOFMEMORY;
    if (SUCCEEDED(hr))
    {
        hr = pDialogEventHandler->QueryInterface(riid, ppv);
        pDialogEventHandler->Release();
    }
    return hr;
}
Cheroot answered 11/12, 2022 at 1:14 Comment(0)
A
-1

You used function prototypes (I believe that is what they are called, forward declarations of functions before the main function) for centerWnd and openDB, but not the CDialogEventHandler_CreateInstance function. Try adding

HRESULT CDialogEventHandler_CreateInstance(REFIID riid, void **ppv);

under

void openDB();

Affirm answered 12/4, 2018 at 15:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.