2011-11-10 10 views
4

最後に、richeditとiczelionのチュートリアルを使用して構文の強調表示を行うことができました。 私はそれを見つけると、それは確かに十分に速くはありません。私はこの一歩前進を考えています:カスタム編集コントロール。しかし、私はそれについてどうやって行くのか分からない。あなたはそれについてどうやって行くのか教えてもらえますか?始めるために私にいくつかの情報を教えてください?たぶんいくつかのチュートリアルやいくつかの本を提案する?カスタム編集コントロールwin32

今私はあなたに私のためにそれを綴ってくれるよう求めているわけではありません。私はこれにC++/ASM/Win32 APIを使用します。あなたの多くはすでにカスタム編集コントロールを作っていると思いますので、あなたの経験を共有することもできます。

おかげで、

Devjeet

+0

[Visual Studioのサンプル](http://archive.msdn.microsoft.com/vcsamplesmfcは)ないワードパッドおよびSUPERPADサンプルに –

+0

おかげを持っていますが、実際にはイムMFCチュートリアルを探しています。 – devjeetroy

+4

英語以外の言語を考慮すると、適切なカスタム編集コントロールは重要ではありません。私はあなたが再考することをお勧めします。 –

答えて

0

あなたが所有者描かれたコントロールに見てみたいしようとしています。 MSDNにはexample of doing this with a list boxがあります。これをEditコントロールに適用することができます。

+0

純粋なWin32オーナー描画コントロールは非常に大量のコードを持っています。エディットボックスで何をしたいのかを教えてもらえればいいかもしれませんし、誰かがあなたのために働く既存のソリューションを知っているかもしれません。 –

+0

ありがとう、response.okので、私はいくつかの基本的な構文を強調表示したいと思います。ファンシーなものはありません。基本的な構文の強調表示。私は開発するのに役立つものを探していました。私は以前にこの規模のものを開発していないし、これが驚異的な経験であることを期待しています。 – devjeetroy

+3

エディットコントロールに「オーナー描画」スタイルがありません。 http://msdn.microsoft.com/en-us/library/windows/desktop/bb775464%28v=vs.85%29.aspxしたがって、あなたが提案したように*適合*することはできません。 – Kissaki

4

私は自分のカスタムエディットコントロールを書いていましたが、うまくいきましたので、ここで私の経験を共有します。このコードは参考になるでしょう...カスタムエディットコントロールが不可能なので(see here)あなた自身の編集コントロールを書く必要があります。一般的な手順は次のとおりです。

// global vars 
int select; // current selection position 
int cursor; // current cursor position 
HWND parent; // parent window 
wchar_t buf[MAXINPUTBUF]; // edit buffer 
WNDPROC oldproc; // old window procedure 

// create custom control window 
hWnd = CreateWindowW(L"static", NULL, WS_CHILD | WS_TABSTOP | SS_LEFT | SS_NOTIFY, 0, 0, 0, 0, parent, NULL, (HINSTANCE)GetWindowLongPtr(parent, GWL_HINSTANCE), NULL); 

// todo: use SetProp() to store all global vars 
oldproc = (WNDPROC)SetWindowLongPtrW(hWnd, GWL_WNDPROC, (LONG_PTR)InputWndProc); 

SetWindowPos(hWnd, HWND_TOP, x, y, cx, cy, 0); 

キーボード入力の表示方法は、hereです。

LRESULT CALLBACK InputWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 

    switch (msg) 
    { 
    case WM_LBUTTONDOWN: 
     //SetFocus(hWnd); 
     PostMessageW(GetParent(hWnd), WM_NEXTDLGCTL, (WPARAM)hWnd, TRUE); 
     break; 

    case WM_KILLFOCUS: 
     HideCaret(hWnd); 
     DestroyCaret(); 
     break; 

    case WM_SETFOCUS: 
     { 
      RECT r; 
      GetClientRect(hWnd, &r); 
      // Create a solid black caret. 
      CreateCaret(hWnd, (HBITMAP) NULL, 2, r.bottom-r.top); 

      ShowCaret(hWnd); 
      InputWndRedraw(hWnd); 

     } 

     return FALSE; 

    case WM_GETDLGCODE: 
     return DLGC_WANTALLKEYS | DLGC_WANTARROWS; 

    case WM_KEYDOWN: 
    { 
     switch (wParam) 
     { 
     case 'V': 
      if (0x8000 & GetKeyState(VK_CONTROL)) 
      { 
       HANDLE h; 
       wchar_t *cb; 
       int len,slen; 

       InputWndDelete(hWnd); 

       OpenClipboard(NULL); 
       h = GetClipboardData(CF_UNICODETEXT); 

       cb = (wchar_t*)GlobalLock(h); 

       if (cb) 
       { 
        memcpy(buf+(cursor+len)*sizeof(wchar_t), buf+cursor*sizeof(wchar_t), (slen-cursor)*sizeof(wchar_t)); 
        memcpy(buf+cursor*sizeof(wchar_t), cb, len*sizeof(wchar_t)); 
       } 

       GlobalUnlock(h); 
       CloseClipboard(); 
       InputWndRedraw(hWnd); 
      } 
      break; 

     case VK_RIGHT: 

       if (cursor-1 >= MAXINPUTBUF || cursor >= (int)wcslen(buf)) 
        break; 

       cursor++; 

       if (!(GetKeyState(VK_SHIFT) & 0x8000)) 
        select = cursor; 

       InputWndRedraw(hWnd); 
       break; 

      case VK_TAB: 
       PostMessageW(GetParent(hWnd), WM_NEXTDLGCTL, GetKeyState(VK_SHIFT) & 0x8000, FALSE); 
       break; 

      case VK_LEFT: 
       if (cursor <= 0) 
        break; 

       cursor--; 

       if (!(GetKeyState(VK_SHIFT) & 0x8000)) 
        select = cursor; 

       InputWndRedraw(hWnd); 
       break; 

      case VK_HOME: 
       cursor = 0; 

       if (!(GetKeyState(VK_SHIFT) & 0x8000)) 
        select = cursor; 

       InputWndRedraw(hWnd); 
       break; 

      case VK_END: 
       cursor = wcslen(buf); 

       if (!(GetKeyState(VK_SHIFT) & 0x8000)) 
        select = cursor; 

       InputWndRedraw(hWnd); 
       break; 

      case VK_DELETE: 
       if (cursor >= (int)wcslen(buf)) 
       { 
        InputWndDelete(hWnd); 
        InputWndRedraw(hWnd); 
        break; 
       } 

       if (select == cursor) 
        select ++; 

       InputWndDelete(hWnd); 
       InputWndRedraw(hWnd); 
      break; 

      case VK_BACK: 

       if (cursor <= 0) 
       { 
        InputWndDelete(hWnd); 
        InputWndRedraw(hWnd); 
        break; 
       } 


       if (select == cursor) 
        cursor --; 


       InputWndDelete(hWnd); 
       InputWndRedraw(hWnd); 
      } 

     } 
     break; 

    case WM_CHAR: 
     if (wParam < VK_SPACE) 
     break; 


     InputWndDelete(hWnd); 

     if (wcslen(buf)+1 < MAXINPUTBUF) 
     { 
      wmemmove(buf+(cursor+1)*sizeof(wchar_t), buf+cursor*sizeof(wchar_t), wcslen(s->buf)-cursor); 
      buf[cursor] = wParam; 
      cursor++; 
      select = cursor; 
     } 

     InputWndRedraw(hWnd); 

     break; 

    case WM_ERASEBKGND: 
     // no flickering 
     return TRUE; 

    case WM_PAINT: 
     { 
      HDC dc; 
      PAINTSTRUCT paint; 

      dc = BeginPaint(hWnd, &paint); 
      InputWndDraw(hWnd, dc); 
      EndPaint(hWnd, &paint); 

     } 
     return TRUE; 

    } 

    return CallWindowProcW(oldproc, hWnd, msg, wParam, lParam); 
} 

は現在選択されているテキストを削除し、次のように私のウィンドウプロシージャが(からカーソルに選択)になります。ウィンドウの

void InputWndDelete(HWND hWnd) 
{ 
    int len; 

    len = wcslen(buf); 

    if (select > cursor) 
    { 
     memcpy(buf+cursor*sizeof(wchar_t), buf+select*sizeof(wchar_t), (len - select)*sizeof(wchar_t)); 
     ZeroMemory(buf+(len-select+cursor)*sizeof(wchar_t), (MAXINPUTBUF-len+select-cursor)*sizeof(wchar_t)); 
     select = cursor; 
    } 
    else if (select < cursor) 
    { 
     memcpy(buf+select*sizeof(wchar_t), buf+cursor*sizeof(wchar_t), (len - cursor)*sizeof(wchar_t)); 
     ZeroMemory(buf+(len-cursor+select)*sizeof(wchar_t), (MAXINPUTBUF-len+cursor-select)*sizeof(wchar_t)); 
     cursor = select; 
    } 
    else 
    { 
     select = cursor; 
    } 
} 

}

描画ウィンドウDC

void InputWndRedraw(HWND hWnd) 
{ 
    HDC hdc; 

    HideCaret(hWnd); 

    hdc = GetDC(hWnd); 
    InputWndDraw(hWnd, hdc); 
    ReleaseDC(hWnd, hdc); 

    ShowCaret(hWnd); 

} 

デバイスコンテキストに入力バッファ(BUF *)を描きます。シンタックスハイライトおよびその他の書式設定機能をここに...

void InputWndDraw(HWND hWnd, HDC hdc) 
{ 
    RECT r,cr; 

    GetClientRect(hWnd, &cr); 

    // draw selected rectangle FillRect()... 

    CopyRect(&r,&cr); 
    DrawTextW(hdc, buf, -1, &r, DT_LEFT | DT_TOP); 


    if (cursor) 
     DrawTextW(hdc, buf, cursor, &r, DT_LEFT | DT_TOP | DT_CALCRECT); 
    else 
     r.right = cr.left; 

    if (GetFocus() == hWnd) 
    { 
     if (r.right > cr.right) 
      SetCaretPos(cr.right, cr.top); 
     else 
      SetCaretPos(r.right, cr.top); 
    } 
} 
関連する問題