summaryrefslogtreecommitdiff
path: root/fpicker/source/win32/filepicker/dibpreview.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'fpicker/source/win32/filepicker/dibpreview.cxx')
-rw-r--r--fpicker/source/win32/filepicker/dibpreview.cxx472
1 files changed, 472 insertions, 0 deletions
diff --git a/fpicker/source/win32/filepicker/dibpreview.cxx b/fpicker/source/win32/filepicker/dibpreview.cxx
new file mode 100644
index 000000000000..fcc369972ff8
--- /dev/null
+++ b/fpicker/source/win32/filepicker/dibpreview.cxx
@@ -0,0 +1,472 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_fpicker.hxx"
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <tchar.h>
+#include "dibpreview.hxx"
+#include <osl/diagnose.h>
+
+#ifndef _COM_SUN_STAR_UI_DIALOG_FILEPREVIEWIMAGEFORMATS_HPP_
+#include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
+#endif
+
+#ifndef _USTRING_HXX_
+#include <rtl/ustring.hxx>
+#endif
+
+#include <stdexcept>
+#include <string>
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::lang::IllegalArgumentException;
+using rtl::OUString;
+
+//------------------------------------------------------------------------
+//
+//------------------------------------------------------------------------
+
+namespace /* private */
+{
+ const LPTSTR CURRENT_INSTANCE = TEXT("CurrInst");
+};
+
+//------------------------------------------------------------------------
+// defines
+//------------------------------------------------------------------------
+
+#define PREVIEWWND_CLASS_NAME TEXT("DIBPreviewWnd###")
+
+// means 3 pixel left and 3 pixel right
+#define HORZ_BODER_SPACE 6
+
+// means 3 pixel top and 3 pixel bottom
+#define VERT_BORDER_SPACE 6
+
+//---------------------------------------------------
+// static member initialization
+//---------------------------------------------------
+
+osl::Mutex CDIBPreview::s_Mutex;
+ATOM CDIBPreview::s_ClassAtom = 0;
+sal_Int32 CDIBPreview::s_RegisterDibPreviewWndCount = 0;
+
+//---------------------------------------------------
+//
+//---------------------------------------------------
+
+CDIBPreview::CDIBPreview(HINSTANCE instance,HWND parent,sal_Bool bShowWindow) :
+ m_Instance(instance)
+{
+ RegisterDibPreviewWindowClass();
+
+ DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
+
+ if (bShowWindow)
+ dwStyle |= WS_VISIBLE;
+
+ m_Hwnd = CreateWindowEx(
+ WS_EX_CLIENTEDGE,
+ PREVIEWWND_CLASS_NAME,
+ TEXT(""),
+ dwStyle,
+ 0, 0, 0, 0,
+ parent,
+ (HMENU)0x0, // for child windows this will
+ // be used as child window identifier
+ m_Instance,
+ (LPVOID)this // pass a pointer to the current
+ // instance of this class
+ );
+
+ bool bSuccess = IsWindow(m_Hwnd);
+
+ OSL_POSTCOND(bSuccess,"Coud not create preview window");
+
+ if (!bSuccess)
+ {
+ UnregisterDibPreviewWindowClass();
+ throw std::runtime_error("Could not create preview window");
+ }
+}
+
+//---------------------------------------------------
+//
+//---------------------------------------------------
+
+CDIBPreview::~CDIBPreview( )
+{
+ // remember: we don't have to destroy the
+ // preview window because it will be destroyed
+ // by it's parent window (the FileOpen dialog)
+ // but we have to unregister the window class
+ //if ( m_bWndClassRegistered )
+ UnregisterDibPreviewWindowClass();
+}
+
+//-------------------------------
+//
+//-------------------------------
+
+sal_Int32 SAL_CALL CDIBPreview::getTargetColorDepth() throw (RuntimeException)
+{
+ HDC hdc = GetDC(m_Hwnd);
+ int clrRes = 0;
+
+ if (hdc)
+ clrRes = GetDeviceCaps(hdc, COLORRES);
+
+ return clrRes;
+}
+
+//-------------------------------
+//
+//-------------------------------
+
+sal_Int32 SAL_CALL CDIBPreview::getAvailableWidth() throw (RuntimeException)
+{
+ RECT rect;
+ bool bRet = GetClientRect(m_Hwnd,&rect);
+
+ sal_Int32 cx = 0;
+
+ if ( bRet )
+ cx = rect.right;
+
+ return cx;
+}
+
+//-------------------------------
+//
+//-------------------------------
+
+sal_Int32 SAL_CALL CDIBPreview::getAvailableHeight() throw (RuntimeException)
+{
+ RECT rect;
+ bool bRet = GetClientRect(m_Hwnd,&rect);
+
+ sal_Int32 cy = 0;
+
+ if ( bRet )
+ cy = rect.bottom;
+
+ return cy;
+}
+
+//-------------------------------
+//
+//-------------------------------
+
+void SAL_CALL CDIBPreview::setImage(sal_Int16 aImageFormat, const Any& aImage)
+ throw (IllegalArgumentException, RuntimeException)
+{
+ PreviewBase::setImage(aImageFormat,aImage);
+
+ // if the any has no value we have an
+ // empty Sequence which clears the
+ // preview window
+ osl::ClearableMutexGuard aGuard(m_PaintLock);
+
+ m_Image.realloc(0);
+ m_ImageData >>= m_Image;
+
+ aGuard.clear();
+
+ InvalidateRect(m_Hwnd,NULL,FALSE);
+ UpdateWindow(m_Hwnd);
+}
+
+//-------------------------------
+//
+//-------------------------------
+
+sal_Bool SAL_CALL CDIBPreview::setShowState(sal_Bool bShowState) throw (RuntimeException)
+{
+ PreviewBase::setShowState(bShowState);
+ ShowWindow(m_Hwnd, m_bShowState ? SW_SHOW : SW_HIDE);
+ return sal_True;
+}
+
+//-------------------------------
+//
+//-------------------------------
+
+sal_Bool SAL_CALL CDIBPreview::getShowState() throw (RuntimeException)
+{
+ return (sal_Bool)IsWindowVisible(m_Hwnd);
+}
+
+//-------------------------------
+//
+//-------------------------------
+
+HWND SAL_CALL CDIBPreview::getWindowHandle() const
+{
+ return m_Hwnd;
+}
+
+//---------------------------------------------------
+//
+//---------------------------------------------------
+
+void SAL_CALL CDIBPreview::onPaint(HWND hWnd, HDC hDC)
+{
+ BITMAPFILEHEADER* pbmfh;
+ BITMAPINFO * pbmi;
+ BYTE * pBits;
+ int cxDib;
+ int cyDib;
+
+ osl::MutexGuard aGuard(m_PaintLock);
+
+ try
+ {
+ pbmfh = reinterpret_cast<BITMAPFILEHEADER*>(m_Image.getArray());
+
+ if ( !IsBadReadPtr( pbmfh, sizeof(BITMAPFILEHEADER)) &&
+ (pbmfh->bfType == ('B' | ('M' << 8))) )
+ {
+ pbmi = reinterpret_cast<BITMAPINFO*>((pbmfh + 1));
+ pBits = reinterpret_cast<BYTE*>(((DWORD)pbmfh) + pbmfh->bfOffBits);
+
+ cxDib = pbmi->bmiHeader.biWidth;
+ cyDib = abs (pbmi->bmiHeader.biHeight);
+
+ SetStretchBltMode(hDC, COLORONCOLOR);
+
+ int nWidth = getAvailableWidth();
+ int nHeight = getAvailableHeight();
+
+ int nX = abs(nWidth - cxDib) / 2;
+ int nY = abs(nHeight - cyDib) / 2;
+
+ int GDIError = GDI_ERROR;
+ GDIError = StretchDIBits(
+ hDC, nX, nY, cxDib, cyDib,
+ 0, 0, cxDib, cyDib, pBits, pbmi,
+ DIB_RGB_COLORS, SRCCOPY);
+
+ OSL_ASSERT(GDI_ERROR != GDIError);
+
+ // paint the border
+ RECT rc;
+
+ if (nY > 0)
+ {
+ // top
+ rc.left = 0;
+ rc.top = 0;
+ rc.right = nWidth;
+ rc.bottom = nY;
+ FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1));
+
+ // bottom
+ rc.left = 0;
+ rc.top = nHeight - nY - 1;
+ rc.right = nWidth;
+ rc.bottom = nHeight;
+ FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1));
+ }
+
+ if (nX > 0)
+ {
+ // left
+ rc.left = 0;
+ rc.top = nY;
+ rc.right = nX;
+ rc.bottom = nHeight - nY;
+ FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1));
+
+ // right
+ rc.left = nWidth - nX - 1;
+ rc.top = nY;
+ rc.right = nWidth;
+ rc.bottom = nHeight - nY;
+ FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1));
+ }
+ }
+ else // clear background
+ {
+ RECT rc;
+ GetClientRect(hWnd,&rc);
+ FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1));
+ }
+ }
+ catch(...)
+ {
+ OSL_ASSERT(sal_False);
+ }
+}
+
+//---------------------------------------------------
+//
+//---------------------------------------------------
+
+LRESULT CALLBACK CDIBPreview::WndProc(
+ HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT lResult = 0;
+
+ switch(uMsg)
+ {
+
+ // we connect a pointer to the current instance
+ // with a window instance via SetProp
+ case WM_CREATE:
+ {
+ LPCREATESTRUCT lpcs =
+ reinterpret_cast< LPCREATESTRUCT >(lParam);
+
+ OSL_ASSERT(lpcs->lpCreateParams);
+
+ // connect the instance handle to the window
+ SetProp(hWnd, CURRENT_INSTANCE, lpcs->lpCreateParams);
+ }
+ break;
+
+ // we remove the window property which connects
+ // a class instance with a window class
+ case WM_NCDESTROY:
+ {
+ // RemoveProp returns the saved value on success
+ if (reinterpret_cast<CDIBPreview*>(
+ RemoveProp(hWnd, CURRENT_INSTANCE)) == NULL)
+ {
+ OSL_ASSERT(false);
+ }
+ }
+ break;
+
+ case WM_PAINT:
+ {
+ CDIBPreview* pImpl = reinterpret_cast<CDIBPreview*>(
+ GetProp(hWnd, CURRENT_INSTANCE));
+
+ OSL_ASSERT(pImpl);
+
+ HDC hDC;
+ PAINTSTRUCT ps;
+
+ hDC = BeginPaint(hWnd,&ps);
+ pImpl->onPaint(hWnd,hDC);
+ EndPaint(hWnd,&ps);
+ }
+ break;
+
+ // ignore this message in order to
+ // avoid flickering during paint
+ case WM_ERASEBKGND:
+ lResult = 1;
+ break;
+
+ default:
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ }
+
+ return lResult;
+}
+
+//---------------------------------------------------
+//
+//---------------------------------------------------
+
+ATOM SAL_CALL CDIBPreview::RegisterDibPreviewWindowClass()
+{
+ osl::MutexGuard aGuard( s_Mutex );
+
+ if (0 == s_ClassAtom)
+ {
+ // register the preview window class
+ WNDCLASSEX wndClsEx;
+ ZeroMemory(&wndClsEx, sizeof(wndClsEx));
+
+ wndClsEx.cbSize = sizeof(wndClsEx);
+ wndClsEx.style = CS_HREDRAW | CS_VREDRAW;
+ wndClsEx.lpfnWndProc = CDIBPreview::WndProc;
+ wndClsEx.hInstance = m_Instance;
+ wndClsEx.hbrBackground = (HBRUSH)(COLOR_INACTIVEBORDER + 1);
+ wndClsEx.lpszClassName = PREVIEWWND_CLASS_NAME;
+
+ // register the preview window class
+ // !!! Win95 - the window class will be unregistered automaticly
+ // if the dll is unloaded
+ // Win2000 - the window class must be unregistered manually
+ // if the dll is unloaded
+ s_ClassAtom = RegisterClassEx(&wndClsEx);
+
+ OSL_POSTCOND(s_ClassAtom,"Could not register preview window class");
+
+ if (0 == s_ClassAtom)
+ throw std::runtime_error("Preview window class could not be registered");
+ }
+
+ // increment the register class counter
+ // so that we keep track of the number
+ // of class registrations
+ //if ( 0 != s_ClassAtom )
+ s_RegisterDibPreviewWndCount++;
+
+ return s_ClassAtom;
+}
+
+//---------------------------------------------------
+//
+//---------------------------------------------------
+
+void SAL_CALL CDIBPreview::UnregisterDibPreviewWindowClass()
+{
+ osl::MutexGuard aGuard( s_Mutex );
+
+ OSL_ASSERT( ( (0 != s_ClassAtom) && (s_RegisterDibPreviewWndCount > 0)) ||
+ ( (0 == s_ClassAtom) && (0 == s_RegisterDibPreviewWndCount) ) );
+
+ // update the register class counter
+ // and unregister the window class if
+ // counter drops to zero
+ if (0 != s_ClassAtom)
+ {
+ s_RegisterDibPreviewWndCount--;
+ OSL_ASSERT(s_RegisterDibPreviewWndCount >= 0);
+ }
+
+ if (0 == s_RegisterDibPreviewWndCount)
+ {
+ UnregisterClass((LPCTSTR)MAKELONG(s_ClassAtom,0),m_Instance);
+ s_ClassAtom = 0;
+ }
+}