normal vs subcassed edit window

Hello. I am a beginner at C++11. I am trying to get to use a subclassed window or edit type of box but I am not certain what is missing please help.

Subclassing in C++ is new to me.



I can use the up and down arrows on my keyboard with the normal window.

I can not use the up and down arrows on my keyboard with the subclassed window.

Why is that and what should I do?



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#define _UNICODE
#define UNICODE

#include <windows.h>
#include <iostream>

wchar_t g_szClassName[] = L"TestOfSubclassing";

LONG g_iResult;

// handle to an Edit control
static HWND hSUBCLASSED;
const int IDB_SUBCLASSED_TEXT  = 1000;

static HWND hNORMAL_TEXT1;
const int IDB_NORMAL_TEXT  = 2000;


LRESULT CALLBACK EditBoxProc(HWND, UINT, WPARAM, LPARAM);

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
     switch(msg)
     {

        case WM_CREATE:
        {

        // A subclassed edit box.
        hSUBCLASSED = CreateWindowExW(
            WS_EX_CLIENTEDGE,
            L"EDIT",
            L"EDIT BOX\r\nSUBCLASSED\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30",
            WS_CHILD | ES_MULTILINE | WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL,
            10,10,
            300,400,
            hwnd,
            (HMENU) IDB_SUBCLASSED_TEXT,
            GetModuleHandle( nullptr ),
            nullptr
            );

        // Subclassing the edit box "IDB_SUBCLASSED_TEXT".
        g_iResult = (LONG)(LONG_PTR)SetWindowLong(GetDlgItem(hwnd, IDB_SUBCLASSED_TEXT), GWL_WNDPROC,  (LONG)(LONG_PTR)EditBoxProc);

        // After subclassing it does not allow the up and down arrows to scroll the text.
        // I can type into the box and use the space bar and use the enter key for a new line, but not scroll with the up and down keys.



        // A non-subclassed edit box.
        hNORMAL_TEXT1 = CreateWindowExW(
            WS_EX_CLIENTEDGE,
            L"edit",
            L"EDIT BOX\r\nNORMAL (NOT SUBCLASSED)\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30",
            WS_CHILD | ES_MULTILINE | WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL,
            350, 10,
            300, 400,
            hwnd,
            (HMENU) IDB_NORMAL_TEXT,
            GetModuleHandle( nullptr ),
            nullptr
            );


        }
        break;


        case WM_CLOSE:
        {
            DestroyWindow(hwnd);
        }
        break;

        case WM_DESTROY:
        {
            PostQuitMessage(0);
        }
        break;

        default:
        {
            return DefWindowProc(hwnd,msg,wParam,lParam);
        }
        break;
        
    }
    return 0;
}

LRESULT CALLBACK EditBoxProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) {

    switch(iMessage) {

        case WM_KEYDOWN: {
            if (wParam == VK_F3)
                MessageBox(hWnd, L"F3 Pressed in Subclassed Edit box.", L"", MB_OK | MB_ICONINFORMATION);
        } break;

        default: {
            return CallWindowProc((WNDPROC)(LONG_PTR)g_iResult, hWnd, iMessage, wParam, lParam);
        } break;

    }

    return 0;

}


int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{

    WNDCLASSEX  wc;
    HWND        hwnd;
    MSG         msg;

    wc.cbClsExtra = 0;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.hCursor = LoadCursor(NULL,IDC_ARROW);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wc.hInstance = hInstance;
    wc.lpfnWndProc =  WndProc;
    wc.lpszClassName = g_szClassName;
    wc.lpszMenuName = NULL;
    wc.style = 0;

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, L"Window Registration Failed!", L"Error!",
        MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }


    hwnd = CreateWindowExW(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        L"Main Test Window",
        WS_OVERLAPPEDWINDOW,
        20, 20, 700, 500,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, L"Window Creation Failed!", L"Error!",
        MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}


Last edited on
Please edit for readability - https://www.cplusplus.com/articles/jEywvCM9/
salem c,

Thank you.

In addition to my original question I now have some more. I am not clear on where to place breaks, inside of the {} or outside of them. See my code. If they are in the wrong place, please tell me.
Similar for return 0; I am not certain when I need them. I think that I used them correctly, but I am still studying C++.

Last edited on
Hello Bob Quarter,

Realize that with subclassing you are 'hooking' into a Window Procedure in a dll somewhere within Windows itself, and the functionality of the control you are subclassing is contained within that external Window Procedure. By calling SetWindowLong() as you are doing, you are telling Windows to send messages to your subclass procedure FIRST. If you do not forward some specific message you receive within your subclass procedure back to the original Window Procedure of the control by calling CallWindowProc(), then whatever functionality is coded within that procedure for that message, e.g., scrolling text in an edit control, it simply will not happen. There is a somewhat commical term for that among us long term Windows Api coders termed 'eating the message'. It may be that is what you are experiencing. Try placing a CallWindowProc() after whatever code you run after intercepting your messages, WM_KEYDOWN or whatever.
Last May I helped member Malibor with subclassing, and posted a working example. Perhaps it will help....

http://www.cplusplus.com/forum/windows/270231/

freddie
freddie1,

Thank you. I am studying what you said and referenced.

The example you gave seems to use the CLI which I am not certain how to use that in my GUI. I am studying this. Thank you.
Last edited on
Registered users can post here. Sign in or register to post.