OpenGL & Windows explorer shell extension?

  • Hi all, i would like to write a plugin for windows 7 explorer. the doc i found are "here": but there is no topic regarding how to use openGL to display a preview of a file.
    Some one can tell me how to use set up a openGl window?

  • Moderators

    I haven't done it myself so treat it as speculation.

    You create an OpenGL window and context as usual, except you don't show the window. This provides you with a HWND window handle.
    Your preview handler will also implement an IPreviewHandler interface. This means that at some point windows will call IPreviewHandler::SetWindow method in which, as a parameter, you will get a HWND handle of the enclosing preview window. From there you can probably put the OpenGL window as a child window of the preview with something like "SetParent":

  • Thanks, i'll see what i can do, but if can give me more info or a snippet it will be more helpfull since it's first time with windows api!
    However thanks again

  • Moderators

    Ouch. That's really hard topic for a "hello winapi".
    Writing COM components is not exactly trivial so I won't be able to provide you with any useful snippets of my own.
    I guess I'd suggest to start with some tutorials on COM architecture like "this one":
    Then try to create a basic handler with minimum functionality. There are tutorials like "this one":
    When you get fairly comfortable with all this COM mumbo-jumbo you can take a look at one of OpenGL with winapi tutorials like "those":
    Qt hides a lot of this but it's good to do it yourself at least once to know how it works.

  • ok at the end i en-up with this code: (unfortunately i have to cut lot of part for posting)

    HRESULT RecipePreviewHandler::CreatePreviewWindow()
    assert(m_hwndPreview == NULL);
    assert(m_hwndParent != NULL);

    HRESULT hr = S_OK;

    GLuint PixelFormat; // Hold the result after searching for a match
    WNDCLASS wc; // Window Class Structure
    DWORD dwStyle; = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Move, And Own DC For Window
    //wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc handles Messages
    wc.cbClsExtra = 0; // No Extra Window Data
    wc.cbWndExtra = 0; // No Extra Window Data
    wc.hInstance = g_hInst;
    wc.hIcon = NULL; // Load The Default Icon
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the default arrow
    wc.hbrBackground = NULL; // No Background required for OpenGL
    wc.lpszMenuName = NULL; // No Menu
    wc.lpszClassName = L"OpenGL";

    if (!RegisterClass(&wc))
    return hr = HRESULT_FROM_WIN32(GetLastError());


    m_hwndPreview =  CreateWindowExW(0, L"OpenGL", NULL,
                                     dwStyle,  // Always create read-only
                                     m_rcParent.right -m_rcParent.left,
                                     m_rcParent.bottom -,
                                     m_hwndParent, NULL, NULL,NULL);
    if (m_hwndPreview == NULL)
        hr = HRESULT_FROM_WIN32(GetLastError());

    hr = HRESULT_FROM_WIN32(GetLastError());

    if (SUCCEEDED(hr))

    sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
    1, // Version Number
    PFD_DRAW_TO_WINDOW | // Format Must Support Window
    PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
    PFD_DOUBLEBUFFER, // Must Support Double Buffering
    PFD_TYPE_RGBA, // Request An RGBA Format
    32, // Select Our Color Depth
    0, 0, 0, 0, 0, 0, // Color Bits Ignored
    0, // No Alpha Buffer
    0, // Shift Bit Ignored
    0, // No Accumulation Buffer
    0, 0, 0, 0, // Accumulation Bits Ignored
    16, // 16Bit Z-Buffer (Depth Buffer)
    0, // No Stencil Buffer
    0, // No Auxiliary Buffer
    PFD_MAIN_PLANE, // Main Drawing Layer
    0, // Reserved
    0, 0, 0 // Layer Masks Ignored

    if (!(hDC=GetDC(m_hwndPreview))) // Did we get the Device Context?
    //abortGLInit("Can't Create A GL Device Context.");
    return HRESULT_FROM_WIN32(GetLastError());

    if (!(PixelFormat=ChoosePixelFormat(hDC, &pfd))) // Did We Find a matching pixel Format?
    //abortGLInit("Can't Find Suitable PixelFormat");
    return HRESULT_FROM_WIN32(GetLastError());

    if (!SetPixelFormat(hDC, PixelFormat, &pfd))
    //abortGLInit("Can't Set The PixelFormat");
    return HRESULT_FROM_WIN32(GetLastError());

    if (!(hRC=wglCreateContext(hDC)))
    //abortGLInit("Can't Create A GL Rendering Context.");
    return HRESULT_FROM_WIN32(GetLastError());

    if (!(wglMakeCurrent(hDC,hRC))) // Try to activate the rendering context

    return HRESULT_FROM_WIN32(GetLastError());

            SetWindowPos(m_hwndPreview, NULL, m_rcParent.left,,
            RECTWIDTH(m_rcParent), RECTHEIGHT(m_rcParent), 
        ShowWindow(m_hwndPreview, SW_SHOW);


    return hr;

    It's basically the Microsoft sample code modified. I still have problem: the window isn't created, i get the error 1400, and some times error 1410.
    plus no rect is passed in SetWindow() function. I don't know what is wrong in my code...

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.