How is the state for COM objects stored?

Viewed 77

Consider this example from MSDN of using a File Open Dialog through COM:

#include <windows.h>
#include <shobjidl.h> 

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | 
        COINIT_DISABLE_OLE1DDE);
    if (SUCCEEDED(hr))
    {
        IFileOpenDialog *pFileOpen;

        // Create the FileOpenDialog object.
        hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, 
                IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));

        if (SUCCEEDED(hr))
        {
            // Show the Open dialog box.
            hr = pFileOpen->Show(NULL);

            // Get the file name from the dialog box.
            if (SUCCEEDED(hr))
            {
                IShellItem *pItem;
                hr = pFileOpen->GetResult(&pItem);
                if (SUCCEEDED(hr))
                {
                    PWSTR pszFilePath;
                    hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);

                    // Display the file name to the user.
                    if (SUCCEEDED(hr))
                    {
                        MessageBoxW(NULL, pszFilePath, L"File Path", MB_OK);
                        CoTaskMemFree(pszFilePath);
                    }
                    pItem->Release();
                }
            }
            pFileOpen->Release();
        }
        CoUninitialize();
    }
    return 0;
}

What I was wondering was how interface methods (Show and GetResult in this case) are able to modify and access object state when no pointer or handle is passed to identify the instance they are operating on.

Having looked on MSDN there does not seem to be anything that explains how this works. I hope someone could provide some insight into how this works

1 Answers

The ABI of GetResult is really HRESULT __stdcall GetResult(IFileDialog*pThis, IShellItem**resultItem).

C++ hides this from you when you use a compiler that is able to follow the COM ABI layout, it will pass the hidden this pointer as the first parameter for you.

If you wanted to do this in pure C it would actually look like this:

IShellItem*pItem;
IFileDialog*pDialog = ...;
...
pDialog->lpVtbl->GetResult(pDialog, &pItem);
Related