2

OK、このプログラムを C++ で作成しています。このプログラムは、クリップボードのテキストを [自動クリップボード] タブ内の編集コントロールに追加することになっています。Unicode テキストをサポートするようにプログラムをセットアップしました。

プログラムの外部にテキストをコピーすると、プログラムはテキストを正しく追加します。しかし、プログラムからテキストをコピーすると、int unicode に変換する必要がある ansi 文字をコピーしているように見えます。

問題がエディット コントロールにあるのか、クリップボードにあるのかわかりません。編集コントロールの出力は Unicode ではありませんか? または、クリップボードは ansi としてコピーし、unicode として貼り付けていますか?

編集: MSDN のドキュメントによると、編集コントロールの WM_COPY は、クリップボードの CF_UNICODETEXT ではなく CF_TEXT モードで処理されることがわかりました: http://msdn.microsoft.com/en-us/library/windows/desktop/ms649022( v=vs.85).aspx

そのため、AutoClipboardEdit コントロールから始まるサブクラスを追加しましたが、何らかの理由で WM_DRAWCLIPBOARD メッセージでヒープ エラーが発生します。だから私はそこに立ち往生しています:

Edit2:クリップボードで使用されているテキスト文字列の割り当てられたメモリを解放しないことで機能しました。この場合、変数の名前は hMem2 です。hMem2 を解放すると、「破損したヒープ」エラーでプログラムがクラッシュするようです。私の推測では、OS 自体がメモリを管理および解放します。データの SetClipboardData 引数がポインターであるため、可能と思われます。また、WM_COPY メッセージを無限ループに送信して、ヒープが永久に増加するかどうかを確認することで、実際にメモリ リークが発生するかどうかをテストしようとしました。しかし、そうは見えませんでした。

したがって、メモリリークがないこと、またはOSが実際にクリップボードを管理および解放していることを誰かに確認してもらう必要があります。

完全なソースコードは次のとおりです。

        #define UNICODE
        #define _UNICODE

        #pragma comment(linker,"\"/manifestdependency:type='win32' \
        name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
        processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
        #pragma comment(lib, "Comctl32.lib")
        #include <tchar.h>
        #include <Windows.h>
        #include <CommCtrl.h>

        #include <sstream>
        using namespace std;
        TCHAR temp[1024];

        enum TabIndexes
        {
            ID_ReadingPageTab,
            ID_AutoClipboardTab
        };
        enum WindowControls
        {
            ID_SelectAll,
            ID_TabControls,
            ID_ReadingPageEdit,
            ID_AutoClipboardEdit,
            ID_AutoClipboardCheckbox,
            ID_AutoReadCheckbox,
            ID_AutoClearCheckbox,
            ID_ReadPauseResumeButton,
            ID_StopButton
        };

        //***************Global Variables***************
        HWND MainWindowHandle;
        HWND ClipboardViewer;
        HWND TabControls;
        HWND ReadingPageEdit;
        HWND AutoClipboardEdit;
        HWND AutoClipboardCheckbox;
        HWND AutoReadCheckbox;
        HWND AutoClearCheckbox;
        HWND ReadPauseResumeButton;
        HWND StopButton;
        RECT WindowReactangle;
        RECT EditControlsDimension;
        HACCEL SelectAll;
        int Textlength;

        void ShowReport()
        {
            LPTSTR ErrorText = NULL;
            FormatMessage
                (
                    FORMAT_MESSAGE_ALLOCATE_BUFFER |
                    FORMAT_MESSAGE_FROM_SYSTEM |
                    FORMAT_MESSAGE_IGNORE_INSERTS, //dwFlags
                    NULL, //lpSource
                    GetLastError(), //dwMessageId
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //dwLanguageId
                    (LPTSTR)&ErrorText, //lpBuffer
                    0, //nSize
                    NULL //*Arguments
                );
            MessageBox(NULL, ErrorText, TEXT("Last Error:"), MB_OK);
        }
        void OutputBox(LPTSTR OutputText)
        {
            MessageBox(NULL, OutputText, _T("WARNING!!!"), MB_OK);
        }

WNDPROC OldProc;
LRESULT CALLBACK EditControl
    (
        HWND hwnd,
        UINT uMsg,
        WPARAM wParam,
        LPARAM lParam
    )
{
    WPARAM StartOfSelectection;
    LPARAM EndOfSelection;
    int SelectionSize;
    int TextSize;
    TCHAR* hMem1;
    TCHAR* hMem2;

    if (uMsg == WM_COPY)
    {
        OpenClipboard(NULL);

        SendMessage(hwnd, EM_GETSEL, (WPARAM)&StartOfSelectection, (LPARAM)&EndOfSelection);
        SelectionSize = EndOfSelection - StartOfSelectection + 1;

        TextSize = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
        TextSize -= (TextSize - EndOfSelection - 1);
        hMem1 = new TCHAR[TextSize]();
        ZeroMemory(hMem1, TextSize*sizeof(TCHAR));
        SendMessage(hwnd, WM_GETTEXT, TextSize, (LONG)hMem1);

        hMem2 = new TCHAR[SelectionSize]();
        ZeroMemory(hMem2, SelectionSize*sizeof(TCHAR));
        for(int Index=0; StartOfSelectection<EndOfSelection; ++StartOfSelectection)
            hMem2[Index++] = hMem1[StartOfSelectection];
        SetClipboardData(CF_UNICODETEXT, (HANDLE)hMem2);

        CloseClipboard();
        delete[] hMem1;
        //delete[] hMem2;
    }
    return OldProc(hwnd, uMsg, wParam, lParam);
}

        void CreateControls(HWND hWndParent)
        {
            GetClientRect(hWndParent, &WindowReactangle);
            const INITCOMMONCONTROLSEX CommonControls = {sizeof(INITCOMMONCONTROLSEX), ICC_TAB_CLASSES};
            InitCommonControlsEx(&CommonControls);
            TabControls = CreateWindow
            (
                WC_TABCONTROL, //lpClassName
                NULL, //lpWindowName
                WS_VISIBLE | WS_CHILD, //dwStyle
                WindowReactangle.left, //x
                WindowReactangle.top, //y
                WindowReactangle.right, //nWidth
                WindowReactangle.bottom - 100, //nHeight
                hWndParent, //hWndParent
                (HMENU)ID_TabControls, //hMenu
                NULL, //hInstance
                NULL //lpParam
            );
            TCITEM TabItemStructure = {0};
            TabItemStructure.mask = TCIF_TEXT;
            TabItemStructure.pszText = _T("Reading Page");
            SendMessage(TabControls, TCM_INSERTITEM, ID_ReadingPageTab, (LPARAM)&TabItemStructure);
            TabItemStructure.pszText = _T("Auto-Clipboard");
            SendMessage(TabControls, TCM_INSERTITEM, ID_AutoClipboardTab, (LPARAM)&TabItemStructure);

            ACCEL AcceleratorStructure;
            AcceleratorStructure.fVirt = FCONTROL | FVIRTKEY;
            AcceleratorStructure.key = 0x41;
            AcceleratorStructure.cmd = ID_SelectAll;
            SelectAll = CreateAcceleratorTable(&AcceleratorStructure, 1);

            ReadingPageEdit = CreateWindow
            (
                _T("EDIT"), //lpClassName
                NULL, //lpWindowName
                WS_VISIBLE | WS_CHILD | WS_VSCROLL | WS_BORDER | ES_MULTILINE, //dwStyle
                5, //x
                30, //y
                WindowReactangle.right - 10, //nWidth
                WindowReactangle.bottom - 135, //nHeight
                TabControls, //hWndParent
                (HMENU)ID_ReadingPageEdit, //hMenu
                NULL, //hInstance
                NULL //lpParam
            );

            AutoClipboardEdit = CreateWindow
            (
                _T("EDIT"), //lpClassName
                NULL, //lpWindowName
                WS_CHILD | WS_VSCROLL | WS_BORDER | ES_MULTILINE, //dwStyle
                5, //x
                30, //y
                WindowReactangle.right - 10, //nWidth
                WindowReactangle.bottom - 135, //nHeight
                TabControls, //hWndParent
                (HMENU)ID_AutoClipboardEdit, //hMenu
                NULL, //hInstance
                NULL //lpParam
            );

            AutoClipboardCheckbox = CreateWindow
            (
                _T("BUTTON"), //lpClassName
                _T("Auto-Clipboard"), //lpWindowName
                BS_AUTOCHECKBOX | WS_VISIBLE | WS_CHILD, //dwStyle
                10, //x
                WindowReactangle.bottom -100 +10, //y
                150, //nWidth
                25, //nHeight
                hWndParent, //hWndParent
                (HMENU)ID_AutoClipboardCheckbox, //hMenu
                NULL, //hInstance
                NULL //lpParam
            );
            SendMessage(AutoClipboardCheckbox, BM_CLICK, TRUE, 0);
    OldProc = (WNDPROC)SetWindowLongPtr(AutoClipboardEdit, GWLP_WNDPROC, (LONG)EditControl);    

            AutoReadCheckbox = CreateWindow
            (
                _T("BUTTON"), //lpClassName
                _T("Auto-Read"), //lpWindowName
                BS_AUTOCHECKBOX | WS_VISIBLE | WS_CHILD, //dwStyle
                10, //x
                WindowReactangle.bottom -100 +35, //y
                150, //nWidth
                25, //nHeight
                hWndParent, //hWndParent
                (HMENU)ID_AutoReadCheckbox, //hMenu
                NULL, //hInstance
                NULL //lpParam
            );

            AutoClearCheckbox = CreateWindow
            (
                _T("BUTTON"), //lpClassName
                _T("Auto-Clear"), //lpWindowName
                BS_AUTOCHECKBOX | WS_VISIBLE | WS_CHILD, //dwStyle
                10, //x
                WindowReactangle.bottom -100 +60, //y
                150, //nWidth
                25, //nHeight
                hWndParent, //hWndParent
                (HMENU)ID_AutoReadCheckbox, //hMenu
                NULL, //hInstance
                NULL //lpParam
            );
        }

        LRESULT WINAPI MainWindowProcedure
            (
                HWND hwnd,
                UINT uMsg,
                WPARAM wParam,
                LPARAM lParam
            )
        {
            switch(uMsg)
            {
            //Clipboard Events
            case WM_CHANGECBCHAIN:
                if ((HWND)wParam == ClipboardViewer)
                    ClipboardViewer = (HWND)lParam;
                return 0;
            case WM_DRAWCLIPBOARD:
                OpenClipboard(NULL);
                SendMessage(AutoClipboardEdit, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
                SendMessage(AutoClipboardEdit, EM_REPLACESEL, 0, (LPARAM)GetClipboardData(CF_UNICODETEXT)); //CF_TEXT //CF_UNICODETEXT
                CloseClipboard();
                break;

            //Window Controls Events
            case WM_COMMAND:
                switch (LOWORD(wParam))
                {
                case ID_SelectAll:
                    if (HIWORD(wParam)==1)
                        SendMessage(GetFocus(), EM_SETSEL, (WPARAM)0, (LPARAM)-1);
                    break;
                case ID_AutoClipboardCheckbox:
                    if (SendMessage(AutoClipboardCheckbox, BM_GETCHECK, 0, 0) == BST_CHECKED)   
                        ClipboardViewer = SetClipboardViewer(hwnd);
                    else
                        ChangeClipboardChain(hwnd, ClipboardViewer);
                    break;
                }
                return 0;

            //Tab Controls Events
            case WM_NOTIFY:
                if (SendMessage(TabControls, TCM_GETCURSEL, 0, 0))
                {
                    ShowWindow(ReadingPageEdit, SW_HIDE);
                    ShowWindow(AutoClipboardEdit, SW_SHOW);
                } else
                {
                    ShowWindow(AutoClipboardEdit, SW_HIDE);
                    ShowWindow(ReadingPageEdit, SW_SHOW);
                }
            break;

            //Main Window Events
            case WM_SIZE:
            {   
                int LOPARAM = lParam & 0xFFFF;
                int HIPARAM = lParam >> 16;
                SetWindowPos(TabControls, NULL, 0, 0, LOPARAM, HIPARAM-100, SWP_DRAWFRAME);
                SetWindowPos(ReadingPageEdit, NULL, 5, 30, LOPARAM-10, HIPARAM-100-35, SWP_DRAWFRAME);
                SetWindowPos(AutoClipboardEdit, NULL, 5, 30, LOPARAM-10, HIPARAM-100-35, SWP_DRAWFRAME);
                SetWindowPos(AutoClipboardCheckbox, NULL, 10, HIPARAM-100+10, 150, 25, SWP_DRAWFRAME);
                SetWindowPos(AutoReadCheckbox, NULL, 10, HIPARAM-100+35, 150, 25, SWP_DRAWFRAME);
                SetWindowPos(AutoClearCheckbox, NULL, 10, HIPARAM-100+60, 150, 25, SWP_DRAWFRAME);
                return 0;
            }
            case WM_CREATE:
                CreateControls(hwnd);
                return 0;
            case WM_DESTROY:
                DestroyAcceleratorTable(SelectAll);
                ChangeClipboardChain(hwnd, ClipboardViewer);
                PostQuitMessage(ERROR_SUCCESS);
                return 0;
            }
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
        }

        void CreateMainWindow()
        {
            WNDCLASSEX WindowClassStructure;
            WindowClassStructure.cbSize = sizeof(WNDCLASSEX);
            WindowClassStructure.style = CS_HREDRAW | CS_VREDRAW;
            WindowClassStructure.lpfnWndProc = MainWindowProcedure;
            WindowClassStructure.cbClsExtra = 0;
            WindowClassStructure.cbWndExtra = 0;
            WindowClassStructure.hInstance = NULL;
            WindowClassStructure.hIcon = LoadIcon(NULL, IDI_INFORMATION);
            WindowClassStructure.hCursor = LoadCursor(NULL, IDC_ARROW);
            WindowClassStructure.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
            WindowClassStructure.lpszMenuName = NULL;
            WindowClassStructure.lpszClassName = _T("MainClass");
            WindowClassStructure.hIconSm = LoadIcon(NULL, IDI_INFORMATION);
            RegisterClassEx(&WindowClassStructure);

            MainWindowHandle = CreateWindow
            (
                _T("MainClass"), //lpClassName
                _T("Clipboard Reader"), //lpWindowName
                WS_VISIBLE | WS_OVERLAPPEDWINDOW, //dwStyle
                CW_USEDEFAULT, //x
                CW_USEDEFAULT, //y
                640, //nWidth
                480, // nHeight
                NULL, //hWndParent
                NULL, //hMenu
                NULL, //hInstance
                NULL //lpParam
            );
        }

        int WINAPI _tWinMain
            (
                HINSTANCE hInstance,
                HINSTANCE hPrevInstance,
                LPTSTR lpCmdLine,
                int nCmdShow
            )
        {
            CreateMainWindow();

            MSG MessageStructure = {0};
            while(MessageStructure.message != WM_QUIT)
            {
                if (PeekMessage(&MessageStructure, NULL, 0, 0, PM_REMOVE))
                {
                    if (!TranslateAccelerator(MainWindowHandle, SelectAll, &MessageStructure))
                    {
                        TranslateMessage(&MessageStructure);
                        DispatchMessage(&MessageStructure);
                    }
                }
            }

            return MessageStructure.wParam;
        }
4

0 に答える 0