MyGUI  3.2.1
MyGUI_WindowsClipboardHandler.cpp
Go to the documentation of this file.
00001 /*
00002  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
00003  * Distributed under the MIT License
00004  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
00005  */
00006 
00007 #include "MyGUI_Precompiled.h"
00008 #include "MyGUI_ClipboardManager.h"
00009 #include "MyGUI_Gui.h"
00010 #include "MyGUI_TextIterator.h"
00011 #include "MyGUI_WindowsClipboardHandler.h"
00012 
00013 #if MYGUI_PLATFORM == MYGUI_PLATFORM_WIN32
00014 
00015 #include <windows.h>
00016 
00017 namespace MyGUI
00018 {
00019 
00020     HWND g_hWnd = NULL;
00021 
00022     BOOL CALLBACK EnumWindowProc(HWND hWnd, LPARAM lParam)
00023     {
00024         DWORD dwProcessID = 0;
00025         GetWindowThreadProcessId(hWnd, &dwProcessID);
00026 
00027         if (dwProcessID != (DWORD)lParam)
00028             return TRUE;
00029 
00030         if (GetParent(hWnd) == NULL)
00031         {
00032             // Нашли. hWnd - то что надо
00033             g_hWnd = hWnd;
00034             return FALSE;
00035         }
00036 
00037         return TRUE;
00038     }
00039 
00040     BOOL CALLBACK EnumChildWindowProc(HWND hWnd, LPARAM lParam)
00041     {
00042         DWORD dwProcessID = 0;
00043         GetWindowThreadProcessId(hWnd, &dwProcessID);
00044 
00045         if (dwProcessID != GetCurrentProcessId())
00046             return TRUE;
00047 
00048         if (GetWindowLongPtr(hWnd, GWLP_HINSTANCE) == lParam)
00049         {
00050             // Нашли. hWnd - то что надо
00051             g_hWnd = hWnd;
00052             return FALSE;
00053         }
00054 
00055         return TRUE;
00056     }
00057 
00058     WindowsClipboardHandler::WindowsClipboardHandler()
00059     {
00060     }
00061 
00062     void WindowsClipboardHandler::initialise()
00063     {
00064         // get executable path
00065         char buf[MAX_PATH];
00066         GetModuleFileName(0, (LPCH)&buf, MAX_PATH);
00067         // get module instance
00068         HINSTANCE instance = GetModuleHandle(buf);
00069 
00070         EnumChildWindows(GetDesktopWindow(), (WNDENUMPROC)EnumWindowProc, (LPARAM)instance);
00071         mHwnd = (size_t)g_hWnd;
00072 
00073         ClipboardManager::getInstance().eventClipboardChanged += newDelegate(this, &WindowsClipboardHandler::handleClipboardChanged);
00074         ClipboardManager::getInstance().eventClipboardRequested += newDelegate(this, &WindowsClipboardHandler::handleClipboardRequested);
00075     }
00076 
00077     void WindowsClipboardHandler::shutdown()
00078     {
00079         ClipboardManager::getInstance().eventClipboardChanged -= newDelegate(this, &WindowsClipboardHandler::handleClipboardChanged);
00080         ClipboardManager::getInstance().eventClipboardRequested -= newDelegate(this, &WindowsClipboardHandler::handleClipboardRequested);
00081     }
00082 
00083     void WindowsClipboardHandler::handleClipboardChanged(const std::string& _type, const std::string& _data)
00084     {
00085         if (_type == "Text")
00086         {
00087             mPutTextInClipboard = TextIterator::getOnlyText(UString(_data));
00088             size_t size = (mPutTextInClipboard.size() + 1) * 2;
00089             //открываем буфер обмена
00090             if (OpenClipboard((HWND)mHwnd))
00091             {
00092                 EmptyClipboard(); //очищаем буфер
00093                 HGLOBAL hgBuffer = GlobalAlloc(GMEM_DDESHARE, size);//выделяем память
00094                 wchar_t* chBuffer = hgBuffer ? (wchar_t*)GlobalLock(hgBuffer) : NULL;
00095                 if (chBuffer)
00096                 {
00097                     memcpy(chBuffer, mPutTextInClipboard.asWStr_c_str(), size);
00098                     GlobalUnlock(hgBuffer);//разблокируем память
00099                     SetClipboardData(CF_UNICODETEXT, hgBuffer);//помещаем текст в буфер обмена
00100                 }
00101                 CloseClipboard(); //закрываем буфер обмена
00102             }
00103         }
00104     }
00105 
00106     void WindowsClipboardHandler::handleClipboardRequested(const std::string& _type, std::string& _data)
00107     {
00108         if (_type == "Text")
00109         {
00110             UString buff;
00111             //открываем буфер обмена
00112             if (OpenClipboard((HWND)mHwnd))
00113             {
00114                 HANDLE hData = GetClipboardData(CF_UNICODETEXT);//извлекаем текст из буфера обмена
00115                 wchar_t* chBuffer = hData ? (wchar_t*)GlobalLock(hData) : NULL;
00116                 if (chBuffer)
00117                 {
00118                     buff = chBuffer;
00119                     GlobalUnlock(hData);//разблокируем память
00120                 }
00121                 CloseClipboard();//закрываем буфер обмена
00122             }
00123             // если в буфере не то что мы ложили, то берем из буфера
00124             if (mPutTextInClipboard != buff)
00125             {
00126                 // вставляем теги, если нуно
00127                 const UString& text = TextIterator::toTagsString(buff);
00128                 _data = text.asUTF8();
00129             }
00130         }
00131     }
00132 
00133 } // namespace MyGUI
00134 
00135 #endif // MYGUI_PLATFORM == MYGUI_PLATFORM_WIN32