OpenGL & Windows explorer shell extension?



  • Hi all, i would like to write a plugin for windows 7 explorer. the doc i found are "here":http://msdn.microsoft.com/en-us/library/windows/desktop/cc144143(v=vs.85).aspx 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":http://msdn.microsoft.com/en-us/library/windows/desktop/ms633541.aspx



  • 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":http://www.codeproject.com/Articles/633/Introduction-to-COM-What-It-Is-and-How-to-Use-It
    Then try to create a basic handler with minimum functionality. There are tutorials like "this one":http://www.codeproject.com/Articles/19744/Using-Preview-Handlers-in-Windows-Vista
    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":http://nehe.gamedev.net/tutorial/lessons_01__05/22004/
    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;
    wc.style = 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))
    {
    UnregisterClass(L"OpenGl",g_hInst);
    return hr = HRESULT_FROM_WIN32(GetLastError());
    }

    dwStyle= WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE;

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

    UnregisterClass(L"OpenGl",g_hInst);
    hr = HRESULT_FROM_WIN32(GetLastError());
    }

    if (SUCCEEDED(hr))
    {
    

    static PIXELFORMATDESCRIPTOR pfd = /
    {
    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, m_rcParent.top,
            RECTWIDTH(m_rcParent), RECTHEIGHT(m_rcParent), 
            SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
        
        ShowWindow(m_hwndPreview, SW_SHOW);
    

    InitGL();
    ReSizeGL(&m_rcParent);
    DrawGLScene();
    }

    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.