派生的mfc ActiveX控件如何更改背景、字体等属性?

qq_38687221 2017-11-15 08:15:39
如题,使用MFC ActiveX控件向导生成一个继承CEdit类的编辑控件,那么生成这个工程之后,接下来该怎么向里面添加属性,得到自己想要的东西呢。比如我想改变这个编辑控件的外形、背景色、字体等,我该怎么做呢?之前生成Activex控件工程的时候,想做这些在添加属性完之后可以OnDraw函数里面绘制,但继承的子类控件在OnDraw函数里面只有一句DoSupperClassPaint()函数,不知道怎么下手,希望有经验的朋友指点下。
...全文
368 点赞 收藏 12
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
qq_38687221 2017-11-27
引用 11 楼 zjq9931 的回复:
[quote=引用 9 楼 qq_38687221 的回复:] [quote=引用 5 楼 zjq9931 的回复:] https://www.cnblogs.com/staring-hxs/archive/2013/01/09/2853126.html 看看这个对你有没有用
里面有些想法下午我已经试过了,依旧不行,在工程中重载OnCtlColor()函数,经设断点,发现程序执行完之后都没有进到这个函数里面,后来,我还是使用sendmessage()函数发送了一个WM_CTLCOLOREDIT消息才进到那个函数,但执行完里面的语句后也没有任何反应,不知道是什么原因。[/quote] 重载onpaint函数呢?[/quote] 没有用!
回复
zjq9931 2017-11-17
引用 9 楼 qq_38687221 的回复:
[quote=引用 5 楼 zjq9931 的回复:] https://www.cnblogs.com/staring-hxs/archive/2013/01/09/2853126.html 看看这个对你有没有用
里面有些想法下午我已经试过了,依旧不行,在工程中重载OnCtlColor()函数,经设断点,发现程序执行完之后都没有进到这个函数里面,后来,我还是使用sendmessage()函数发送了一个WM_CTLCOLOREDIT消息才进到那个函数,但执行完里面的语句后也没有任何反应,不知道是什么原因。[/quote] 重载onpaint函数呢?
回复
赵4老师 2017-11-16
注释掉DoSupperClassPaint(),全部改为自绘?
回复
qq_38687221 2017-11-16
引用 6 楼 zgl7903 的回复:
那我建议你使用 RichEdit 控件, 比较容易操作, MSDN 上类似于编辑框功能的参考代码

/*
Displaying Keyboard Input
The example in this section shows how an application can receive characters from the keyboard, display them in the client area of a window, and update the position of the caret with each character typed. It also demonstrates how to move the caret in response to the left arrow, right arrow, home and end keystrokes, and shows how to highlight selected text in response to the shift+right arrow key combination. 

During processing of the WM_CREATE message, the window procedure shown in the example allocates a 64K buffer for storing keyboard input. It also retrieves the metrics of the currently loaded font, saving the height and average width of characters in the font. The height and width are used in processing the WM_SIZE message to calculate the line length and maximum number of lines, based on the size of the client area. 

The window procedure creates and displays the caret when processing the WM_SETFOCUS message. It hides and deletes the caret when processing the WM_KILLFOCUS message. 

When processing the WM_CHAR message, the window procedure displays characters, stores them in the input buffer, and updates the caret position. The window procedure also converts tab characters to four consecutive space characters. Backspace, linefeed, and escape characters generate a beep, but are not otherwise processed. 

The window procedure performs the left, right, end, and home caret movements when processing the WM_KEYDOWN message. While processing the action of the right arrow key, the window procedure checks the state of the shift key and, if it is down, selects the character to the right of the caret as the caret is moved. 

Note that the following code is written so that it can be compiled either as Unicode or as ANSI. If the source code defines UNICODE, strings are handled as Unicode characters; otherwise, they are handled as ANSI characters. 
*/
感谢提供编辑框编程的一些信息,如果实在找不到方法从派生的控件中设置自己想要的属性,那估计就真得自己完完整整做一个编辑框控件了,但这个难度是非常大的,键盘、鼠标的消息全都要自己处理。再顶顶,看看还有没有回复。
回复
qq_38687221 2017-11-16
引用 5 楼 zjq9931 的回复:
https://www.cnblogs.com/staring-hxs/archive/2013/01/09/2853126.html 看看这个对你有没有用
里面有些想法下午我已经试过了,依旧不行,在工程中重载OnCtlColor()函数,经设断点,发现程序执行完之后都没有进到这个函数里面,后来,我还是使用sendmessage()函数发送了一个WM_CTLCOLOREDIT消息才进到那个函数,但执行完里面的语句后也没有任何反应,不知道是什么原因。
回复
zgl7903 2017-11-16


        case WM_KEYDOWN: 
            switch (wParam) 
            { 
                case VK_LEFT:   // LEFT ARROW 
 
                    // The caret can move only to the beginning of 
                    // the current line. 
 
                    if (nCaretPosX > 0) 
                    { 
                        HideCaret(hwndMain); 
 
                        // Retrieve the character to the left of 
                        // the caret, calculate the character's 
                        // width, then subtract the width from the 
                        // current horizontal position of the caret 
                        // to obtain the new position. 
 
                        ch = pchInputBuf[--nCurChar]; 
                        hdc = GetDC(hwndMain); 
                        GetCharWidth32(hdc, ch, ch, &nCharWidth); 
                        ReleaseDC(hwndMain, hdc); 
                        nCaretPosX = max(nCaretPosX - nCharWidth, 
                            0); 
                        ShowCaret(hwndMain); 
                    } 
                    break; 
 
                case VK_RIGHT:  // RIGHT ARROW 
 
                    // Caret moves to the right or, when a carriage 
                    // return is encountered, to the beginning of 
                    // the next line. 
 
                    if (nCurChar < cch) 
                    { 
                        HideCaret(hwndMain); 
 
                        // Retrieve the character to the right of 
                        // the caret. If it's a carriage return, 
                        // position the caret at the beginning of 
                        // the next line. 
 
                        ch = pchInputBuf[nCurChar]; 
                        if (ch == 0x0D) 
                        { 
                            nCaretPosX = 0; 
                            nCaretPosY++; 
                        } 
 
                        // If the character isn't a carriage 
                        // return, check to see whether the SHIFT 
                        // key is down. If it is, invert the text 
                        // colors and output the character. 
 
                        else 
                        { 
                            hdc = GetDC(hwndMain); 
                            nVirtKey = GetKeyState(VK_SHIFT); 
                            if (nVirtKey & SHIFTED) 
                            { 
                                crPrevText = SetTextColor(hdc, 
                                    RGB(255, 255, 255)); 
                                crPrevBk = SetBkColor(hdc, 
                                    RGB(0,0,0)); 
                                TextOut(hdc, nCaretPosX, 
                                    nCaretPosY * dwCharY, 
                                    &ch, 1); 
                                SetTextColor(hdc, crPrevText); 
                                SetBkColor(hdc, crPrevBk); 
                            } 
 
                            // Get the width of the character and 
                            // calculate the new horizontal 
                            // position of the caret. 
 
                            GetCharWidth32(hdc, ch, ch, &nCharWidth); 
                            ReleaseDC(hwndMain, hdc); 
                            nCaretPosX = nCaretPosX + nCharWidth; 
                        } 
                        nCurChar++; 
                        ShowCaret(hwndMain); 
                        break; 
                    } 
                    break; 
 
                case VK_UP:     // UP ARROW 
                case VK_DOWN:   // DOWN ARROW 
                    MessageBeep(0xFFFFFFFF); 
                    return 0; 
 
                case VK_HOME:   // HOME 
 
                    // Set the caret's position to the upper left 
                    // corner of the client area. 
 
                    nCaretPosX = nCaretPosY = 0; 
                    nCurChar = 0; 
                    break; 
 
                case VK_END:    // END  
 
                    // Move the caret to the end of the text. 
 
                    for (i=0; i < cch; i++) 
                    { 
                        // Count the carriage returns and save the 
                        // index of the last one. 
 
                        if (pchInputBuf[i] == 0x0D) 
                        { 
                            cCR++; 
                            nCRIndex = i + 1; 
                        } 
                    } 
                    nCaretPosY = cCR; 
 
                    // Copy all text between the last carriage 
                    // return and the end of the keyboard input 
                    // buffer to a temporary buffer. 
 
                    for (i = nCRIndex, j = 0; i < cch; i++, j++) 
                        szBuf[j] = pchInputBuf[i]; 
                    szBuf[j] = TEXT('\0'); 
 
                    // Retrieve the text extent and use it 
                    // to set the horizontal position of the 
                    // caret. 
 
                    hdc = GetDC(hwndMain); 
                    GetTextExtentPoint32(hdc, szBuf, lstrlen(szBuf), 
                        &sz); 
                    nCaretPosX = sz.cx; 
                    ReleaseDC(hwndMain, hdc); 
                    nCurChar = cch; 
                    break; 
 
                default: 
                    break; 
            } 
            SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); 
            break; 
 
        case WM_PAINT: 
            if (cch == 0)       // nothing in input buffer 
                break; 
 
            hdc = BeginPaint(hwndMain, &ps); 
            HideCaret(hwndMain); 
 
            // Set the clipping rectangle, and then draw the text 
            // into it. 
 
            SetRect(&rc, 0, 0, dwLineLen, dwClientY); 
            DrawText(hdc, pchInputBuf, -1, &rc, DT_LEFT); 
 
            ShowCaret(hwndMain); 
            EndPaint(hwndMain, &ps); 
            break; 
        
        // Process other messages. 
        
        case WM_DESTROY: 
            PostQuitMessage(0); 
 
            // Free the input buffer. 
 
            GlobalFree((HGLOBAL) pchInputBuf); 
            UnregisterHotKey(hwndMain, 0xAAAA); 
            break; 
 
        default: 
            return DefWindowProc(hwndMain, uMsg, wParam, lParam); 
    } 
    return NULL; 
} 
回复
zgl7903 2017-11-16
接上文

#define BUFSIZE 65535 
#define SHIFTED 0x8000 
 
LONG APIENTRY MainWndProc(HWND hwndMain, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    HDC hdc;                   // handle to device context 
    TEXTMETRIC tm;             // structure for text metrics 
    static DWORD dwCharX;      // average width of characters 
    static DWORD dwCharY;      // height of characters 
    static DWORD dwClientX;    // width of client area 
    static DWORD dwClientY;    // height of client area 
    static DWORD dwLineLen;    // line length 
    static DWORD dwLines;      // text lines in client area 
    static int nCaretPosX = 0; // horizontal position of caret 
    static int nCaretPosY = 0; // vertical position of caret 
    static int nCharWidth = 0; // width of a character 
    static int cch = 0;        // characters in buffer 
    static int nCurChar = 0;   // index of current character 
    static PTCHAR pchInputBuf; // address of input buffer 
    int i, j;                  // loop counters 
    int cCR = 0;               // count of carriage returns 
    int nCRIndex = 0;          // index of last carriage return 
    int nVirtKey;              // virtual-key code 
    TCHAR szBuf[128];          // temporary buffer 
    TCHAR ch;                  // current character 
    PAINTSTRUCT ps;            // required by BeginPaint 
    RECT rc;                   // output rectangle for DrawText 
    SIZE sz;                   // string dimensions 
    COLORREF crPrevText;       // previous text color 
    COLORREF crPrevBk;         // previous background color 
 
    switch (uMsg) 
    { 
        case WM_CREATE: 
 
            // Get the metrics of the current font. 
 
            hdc = GetDC(hwndMain); 
            GetTextMetrics(hdc, &tm); 
            ReleaseDC(hwndMain, hdc); 
 
            // Save the average character width and height. 
 
            dwCharX = tm.tmAveCharWidth; 
            dwCharY = tm.tmHeight; 
 
            // Allocate a buffer to store keyboard input. 
 
            pchInputBuf = (LPTSTR) GlobalAlloc(GPTR, 
                BUFSIZE * sizeof(TCHAR)); 
            return 0; 
 
        case WM_SIZE: 
 
            // Save the new width and height of the client area. 
 
            dwClientX = LOWORD(lParam); 
            dwClientY = HIWORD(lParam); 
 
            // Calculate the maximum width of a line and the 
            // maximum number of lines in the client area. 
            
            dwLineLen = dwClientX - dwCharX; 
            dwLines = dwClientY / dwCharY; 
            break; 
 
 
        case WM_SETFOCUS: 
 
            // Create, position, and display the caret when the 
            // window receives the keyboard focus. 
 
            CreateCaret(hwndMain, (HBITMAP) 1, 0, dwCharY); 
            SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); 
            ShowCaret(hwndMain); 
            break; 
 
        case WM_KILLFOCUS: 
 
            // Hide and destroy the caret when the window loses the 
            // keyboard focus. 
 
            HideCaret(hwndMain); 
            DestroyCaret(); 
            break; 
 
        case WM_CHAR: 
            switch (wParam) 
            { 
                case 0x08:  // backspace 
                case 0x0A:  // linefeed 
                case 0x1B:  // escape 
                    MessageBeep(0xFFFFFFFF); 
                    return 0; 
 
                case 0x09:  // tab 
 
                    // Convert tabs to four consecutive spaces. 
 
                    for (i = 0; i < 4; i++) 
                        SendMessage(hwndMain, WM_CHAR, 0x20, 0); 
                    return 0; 
 
                case 0x0D:  // carriage return 
 
                    // Record the carriage return and position the 
                    // caret at the beginning of the new line. 
 
                    pchInputBuf[cch++] = 0x0D; 
                    nCaretPosX = 0; 
                    nCaretPosY += 1; 
                    break; 
 
                default:    // displayable character 
 
                    ch = (TCHAR) wParam; 
                    HideCaret(hwndMain); 
 
                    // Retrieve the character's width and output 
                    // the character. 
 
                    hdc = GetDC(hwndMain); 
                    GetCharWidth32(hdc, (UINT) wParam, (UINT) wParam, 
                        &nCharWidth); 
                    TextOut(hdc, nCaretPosX, nCaretPosY * dwCharY, 
                        &ch, 1); 
                    ReleaseDC(hwndMain, hdc); 
 
                    // Store the character in the buffer. 
 
                    pchInputBuf[cch++] = ch; 
 
                    // Calculate the new horizontal position of the 
                    // caret. If the position exceeds the maximum, 
                    // insert a carriage return and move the caret 
                    // to the beginning of the next line. 
 
                    nCaretPosX += nCharWidth; 
                    if ((DWORD) nCaretPosX > dwLineLen) 
                    { 
                        nCaretPosX = 0; 
                        pchInputBuf[cch++] = 0x0D; 
                        ++nCaretPosY; 
                    } 
                    nCurChar = cch; 
                    ShowCaret(hwndMain); 
                    break; 
            } 
            SetCaretPos(nCaretPosX, nCaretPosY * dwCharY); 
            break; 
 
回复
zgl7903 2017-11-16
那我建议你使用 RichEdit 控件, 比较容易操作, MSDN 上类似于编辑框功能的参考代码

/*
Displaying Keyboard Input
The example in this section shows how an application can receive characters from the keyboard, display them in the client area of a window, and update the position of the caret with each character typed. It also demonstrates how to move the caret in response to the left arrow, right arrow, home and end keystrokes, and shows how to highlight selected text in response to the shift+right arrow key combination. 

During processing of the WM_CREATE message, the window procedure shown in the example allocates a 64K buffer for storing keyboard input. It also retrieves the metrics of the currently loaded font, saving the height and average width of characters in the font. The height and width are used in processing the WM_SIZE message to calculate the line length and maximum number of lines, based on the size of the client area. 

The window procedure creates and displays the caret when processing the WM_SETFOCUS message. It hides and deletes the caret when processing the WM_KILLFOCUS message. 

When processing the WM_CHAR message, the window procedure displays characters, stores them in the input buffer, and updates the caret position. The window procedure also converts tab characters to four consecutive space characters. Backspace, linefeed, and escape characters generate a beep, but are not otherwise processed. 

The window procedure performs the left, right, end, and home caret movements when processing the WM_KEYDOWN message. While processing the action of the right arrow key, the window procedure checks the state of the shift key and, if it is down, selects the character to the right of the caret as the caret is moved. 

Note that the following code is written so that it can be compiled either as Unicode or as ANSI. If the source code defines UNICODE, strings are handled as Unicode characters; otherwise, they are handled as ANSI characters. 
*/
回复
zjq9931 2017-11-16
https://www.cnblogs.com/staring-hxs/archive/2013/01/09/2853126.html 看看这个对你有没有用
回复
qq_38687221 2017-11-16
引用 3 楼 zgl7903 的回复:
https://technet.microsoft.com/zh-cn/library/9s2s80tk(v=vs.110).aspx The DoSuperclassPaint member function will work only with those control types that allow a device context to be passed as the wParam of a WM_PAINT message. This includes some of the standard Windows controls, such as SCROLLBAR and BUTTON, and all the common controls. For controls that do not support this behavior, you will have to provide your own code to properly display an inactive control.
这篇文章之前已经看过了,在OnOcmCommand()这个函数这一截没有完全看懂,文章的大概意思是说容器不想接收派生控件发送的消息,所以创建了一个反射窗口函数,在这个函数里面处理控件发送出去的消息,那么我应该怎么处理呢? 另外,下面英文描述跟我的问题其实没有多大关系,编辑控件也是标准控件,所以DoSupperClassPaint()函数是可以用的。 我的问题其实很简单,就是想在ActiveX控件工程派生的编辑控件中,修改它的背景色和文本颜色,及添加一些自定义的属性,想知道该怎么做而已。而msdn在这方面的描述也就只有上面那篇文章,细节上的处理就没有提到,查了很久都没查到什么,有没有大神出来顶一顶啊!
回复
zgl7903 2017-11-16
https://technet.microsoft.com/zh-cn/library/9s2s80tk(v=vs.110).aspx The DoSuperclassPaint member function will work only with those control types that allow a device context to be passed as the wParam of a WM_PAINT message. This includes some of the standard Windows controls, such as SCROLLBAR and BUTTON, and all the common controls. For controls that do not support this behavior, you will have to provide your own code to properly display an inactive control.
回复
qq_38687221 2017-11-16
引用 1 楼 zhao4zhong1 的回复:
注释掉DoSupperClassPaint(),全部改为自绘?
注释掉该语句,会出现一个问题,一开始加载该控件的时候没有绘图,要拉动他的时候才会重新绘制。但我觉得注释掉然后重绘的方法应该不对,我在msdn上有看过一个例子,同样是派生了一个列表框控件,该作者想在该控件上点击的时候显示文字,但因为这个控件是派生的控件,ondraw函数里面都已经做好,所以不能在里面进行绘图输出,反而他是通过点击时发送了一个消息让控件自己处理文字的绘制,所以我想绘制背景应该也可以通过相似的方法,但找到一个WM_CTLCOLOREDIT消息,但似乎没有像上文提到的列表控件那样的用法,不知道该如何下手。
回复
相关推荐
发帖
ATL
创建于2007-09-28

3216

社区成员

ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
申请成为版主
帖子事件
创建了帖子
2017-11-15 08:15
社区公告
暂无公告