0

TRichEditのテキストを垂直方向の中央に揃えるにはどうすればよいですか。パラガフを水平方向に整列させるためのプロパティがありますが、垂直方向に整列するためのプロパティはありません。私はC++ビルダーを使用しています。

4

2 に答える 2

0

TRichEditは、MS RichEditコンポーネントの単なるラッパーであるため、ハンドルを取得し、WinAPIを使用して直接操作できます:http://msdn.microsoft.com/en-us/library/bb787873(VS.85).aspx

于 2010-12-29T15:32:42.430 に答える
0

Richeditインターフェースには、このためのメソッドがありません。ただし、既存のメッセージを使用してそれを行うのはかなり簡単です。EM_POSFROMCHARを使用して、コントロールの最初と最後の文字の垂直位置を取得し、最後の文字の高さを追加します。次に、テキストを垂直方向に中央揃えするために必要なコントロールの上部からのオフセットを計算します。次に、EM_SETRECTメッセージを使用して、コントロール内でtxtが描画される位置を調整します。

テキストが変更されたときにこれを動的に実行する場合は、コントロールをサブクラス化し、適切なメッセージを処理する必要があります。以下のコードスニペットを参照してください。

// in WM_CREATE of parent window or when control is created
hwndTextbox = CreateWindowEx (0, MSFTEDIT_CLASS, (WCHAR*)yourtext, 
    ES_MULTILINE | WS_VISIBLE | WS_SIZEBOX | WS_CHILD | WS_CLIPSIBLINGS,
    left, top, width, height,
    hwnd, NULL, hInst, NULL);
    SetProp (hwndTextbox, L"oldproc", (HANDLE)(ULONG_PTR)GetWindowLong (hwndTextbox, GWL_WNDPROC));
    SetWindowLong (hwndTextbox, GWL_WNDPROC, (DWORD)(LRESULT)RicheditWndProc);

// after control has been drawn eg in WM_SIZE of parent window
{
    RECT rclBox;
    SendMessage(hwndTextbox, EM_GETRECT, 0, (LPARAM)&rclBox);
    rclBox.top = vertoffset;    // previously saved vertical offset for control either globally or as window property of control
    SendMessage(hwndTextbox, EM_SETRECT, 0, (LPARAM)&rclBox);
    InvalidateRect(hwndTextbox, NULL, TRUE);
}


LRESULT WINAPI RicheditWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    static BOOL fVcentre;   // will need to be stored as a window property if more than one control
    WNDPROC lpOldProc;
    CHARFORMAT cf;
    lpOldProc = (WNDPROC)GetProp( hwnd, L"oldproc" );
    switch( msg )
    {
    case WM_TIMER:
        // use timer to ensure text is redrawn before positioning
        switch(wParam)
        {
        case 1:
            KillTimer(hwnd, 1);
            {
                POINTL pt, pt1;
                RECT rcl;
                RECT rclParent;
                int last, height=0, offset, current;
                SendMessage (hwnd, EM_GETSEL, (WPARAM)&current, 0);
                SendMessage(hwnd, EM_GETRECT, 0, (LPARAM)&rcl);
                GetClientRect(GetParent(hwnd), &rclParent);
                SendMessage (hwnd, EM_SETSEL, 0, -1);
                SendMessage (hwnd, EM_GETSEL, 0, (LPARAM)&last);
                SendMessage(hwnd, EM_POSFROMCHAR, (WPARAM)&pt, 0);
                SendMessage(hwnd, EM_POSFROMCHAR, (WPARAM)&pt1, last);
                // get height of last character
                SendMessage (hwnd, EM_SETSEL, last-1, last);
                memset(&cf, 0, sizeof cf);
                cf.cbSize = sizeof cf;
                SendMessage (hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
                if(cf.dwMask & CFM_SIZE)
                    height = cf.yHeight/15;
                height = height + pt1.y - pt.y;
                vertoffset = (rcl.bottom - height)/2;
                ifvertoffset > 0) // vertoffset can be < 0 if needed
                {
                    rcl.top = vertoffset;
                    SendMessage(hwnd, EM_SETRECT, 0, (LPARAM)&rcl);
                    InvalidateRect(hwnd, NULL, TRUE);
                }
                SendMessage (hwnd, EM_SETSEL, current, current);
            }
            break;
        }
        break;

        case WM_DESTROY:                         //  Put back old window proc and
                SetWindowLong( hwnd, GWL_WNDPROC, (DWORD)(LRESULT)lpOldProc );
                RemoveProp( hwnd, L"oldproc" );              //  remove window property
                break;

    case WM_KEYUP:
    case WM_CHAR:
    case WM_PASTE:
    case WM_CUT:
    case EM_UNDO:
    case EM_REDO:
    // any message that modifies the text
        if(fVcentre)
            SetTimer(hwnd, 1, 100, NULL);
        break;

    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case ID_TFVCENTRE:  // id to centre text
            {
                POINTL pt, pt1;
                RECT rcl;
                RECT rclParent;
                int last, height=0, offset, current;
                fVcentre = !fVcentre;
                SendMessage(hwnd, EM_GETRECT, 0, (LPARAM)&rcl);
                if(fVcentre)
                {
                    GetClientRect(GetParent(hwnd), &rclParent);
                    SendMessage (hwnd, EM_GETSEL, (WPARAM)&current, 0);
                    SendMessage (hwnd, EM_SETSEL, 0, -1);
                    SendMessage (hwnd, EM_GETSEL, 0, (LPARAM)&last);
                    SendMessage(hwnd, EM_POSFROMCHAR, (WPARAM)&pt, 0);
                    SendMessage(hwnd, EM_POSFROMCHAR, (WPARAM)&pt1, last);
                    // get height of last character
                    SendMessage (hwnd, EM_SETSEL, last-1, last);
                    memset(&cf, 0, sizeof cf);
                    cf.cbSize = sizeof cf;
                    SendMessage (hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
                    if(cf.dwMask & CFM_SIZE)
                        height = cf.yHeight/15;
                    height = height + pt1.y - pt.y;
                    vertoffset = (rcl.bottom - height)/2;
                    ifvertoffset > 0)
                    {
                        rcl.top = vertoffset 
                        SendMessage(hwnd, EM_SETRECT, 0, (LPARAM)&rcl);
                        InvalidateRect(hwnd, NULL, TRUE);
                    }
                    SendMessage (hwnd, EM_SETSEL, current, current);
                }
                else
                {
                    rcl.top = 0;
                    vertoffset = 0;
                    SendMessage(hwnd, EM_SETRECT, 0, (LPARAM)&rcl);
                    InvalidateRect(hwnd, NULL, TRUE);
                }
            }
            break;
        }
        break;

    }                        //  Pass all non-custom messages to old window proc
    return( CallWindowProc( lpOldProc, hwnd, msg, wParam, lParam ) );
}

于 2020-10-02T11:09:10.513 に答える