Simple example: Subclassing of an edit control

New to FreeBASIC? Post your questions here.
jj2007
Posts: 1259
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Simple example: Subclassing of an edit control

Postby jj2007 » Aug 30, 2018 19:24

Note this is not an exhaustive example how to create a Windows GUI application; it just gives you the minimum skeleton to perform subclassing.
You will get plenty of useless warnings - you can ignore them (more). The example builds and runs fine with Gas & Gcc in 32- or 64-bit mode.

Code: Select all

#if 0   ' *** simple example how to subclass an edit control ***
  This example creates a Windows application with a static and an edit control
  The edit control is subclassed and does not accept any char above Ascii 57, i.e. the number 9
  The source consists of three major parts:
  - Function SubEdit is a callback procedure (added with SetWindowLongPtr) where we decide which keypresses to accept
  - Function WndProc is the main window's callback procedure; here, we can handle various events
  - Function WinMain does the setup of the main window, and creates the message loop
#endif
#include "windows.bi"
Dim Shared as Handle hEdit, hStatic
Dim Shared as any ptr PreviousWinProc

Function SubEdit(hWnd As HWND, uMsg As UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
  ' we ignore all messages and pass them on to Windows via CallWindowProc, with one exception:
  ' if Windows tells us that it wants to pass a CHAR that we don't like, WE BLOCK IT:
  if uMsg=WM_CHAR then   ' we are only interested in the WM_CHAR message:
   if wParam>57 then
      SendMessageW(hStatic, WM_SETTEXT, 0, StrPtr("chars above '9' are not allowed"))
      return 0   ' bingo: we do NOT process this message
   else
      SendMessageW(hStatic, WM_SETTEXT, 0, StrPtr("ok"))
   endif
  endif
  return CallWindowProc(PreviousWinProc, hWnd, uMsg, wParam, lParam) ' perform default processing
End Function

Function WndProc(hWnd As HWND, msg As UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
  Select Case msg
  Case WM_CREATE   ' we create two child controls here
   hStatic=CreateWindowEx(0, "static", "start typing now...",_
   WS_CHILD Or WS_VISIBLE, 0, 0, 1, 1, hWnd, 100, 0, 0)
   hEdit=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", 0,_
   WS_CHILD Or WS_VISIBLE or ES_MULTILINE, 0, 0, 1, 1, hWnd, 101, 0, 0)
   PreviousWinProc=SetWindowLongPtr(hEdit, GWLP_WNDPROC, @SubEdit)
   SetFocus(hEdit)   ' start typing immediately
  Case WM_SIZE   ' we adjust the child controls to the main window
   Dim As RECT rc
   GetClientRect(hWnd, @rc)
   MoveWindow(hStatic, 3, 3, rc.right-6, 20, 0)
   MoveWindow(hEdit, 3, 23, rc.right-6, rc.bottom-26, 0)
  Case WM_DESTROY
      PostQuitMessage(0)   ' close the main window
  End Select
  return DefWindowProc(hwnd, msg, wParam, lParam)
End Function

Function WinMain(hInstance As HINSTANCE, hPrevInstance As HINSTANCE, lpCmdLine As LPSTR, nShowCmd As Integer) As Integer
   Dim As WNDCLASSEX wc
   Dim As MSG msg
   Dim As string classname="FbGui"
   wc.cbSize = sizeof(WNDCLASSEX)
   wc.hbrBackground = COLOR_BTNFACE+1
   wc.hCursor = LoadCursor(0, IDC_ARROW)
   wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION)
   wc.hIconSm = wc.hIcon
   wc.hInstance = hInstance
   wc.lpfnWndProc = @WndProc
   wc.lpszClassName = StrPtr(classname)
   wc.style = CS_HREDRAW Or CS_VREDRAW
   RegisterClassEx(@wc)

   if CreateWindowEx(0, wc.lpszClassName, "Simple subclassing example",_
   WS_OVERLAPPEDWINDOW Or WS_VISIBLE, (GetSystemMetrics(SM_CXSCREEN) / 2) - 150,_
   (GetSystemMetrics(SM_CYSCREEN) / 2) - 100, 300, 200, 0, 0, hInstance, 0)=0 then
          MessageBox(0, "Creating hMain failed miserably", 0, MB_OK)
          return 0
   End If

   While GetMessage(@msg, 0, 0, 0)
      TranslateMessage(@msg)
      DispatchMessage(@msg)
   Wend

   return msg.wParam
End Function

' ----------- end of functions, the main program starts here: -----------
WinMain(GetModuleHandle(NULL), NULL, COMMAND(), SW_NORMAL)
RNBW
Posts: 192
Joined: Apr 11, 2015 11:06
Location: UK

Re: Simple example: Subclassing of an edit control

Postby RNBW » Aug 31, 2018 8:48

An interesting start to the subject. Please continue with more examples.
jj2007
Posts: 1259
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Simple example: Subclassing of an edit control

Postby jj2007 » Aug 31, 2018 16:17

OK, here is another one:

Code: Select all

#if 0   ' *** simple example how to subclass an edit control ***
  This example creates a Windows application with a static and an edit control
  The edit control is subclassed and does not accept anything above Ascii 57, i.e. the number 9
  The source consists of three major parts:
  - Function SubEdit is a callback procedure (added with SetWindowLongPtr) where we decide which keypresses to accept
  - Function WndProc is the main window's callback procedure; here, we can handle various events
  - Function WinMain does the setup of the main window, and creates the message loop
  *** Note this is not an exhaustive example how to create a Windows GUI application; it just gives you the
  minimum skeleton to perform subclassing. You will get plenty of useless warnings - you can ignore them ***
#endif
#include "windows.bi"
Dim Shared as Handle hEdit(2)
Dim Shared as Handle hBrush(2)
Dim Shared as Handle hStatic
Dim Shared as any ptr PreviousWinProc

Function SubEdit(hWnd As HWND, uMsg As UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
  ' we ignore all messages and pass them on to Windows via CallWindowProc, with one exception:
  ' if Windows tells us that it wants to pass a CHAR that we don't like, WE BLOCK IT:
  if uMsg=WM_CHAR then   ' we are interested in the WM_CHAR message:

   if wParam>57 then
      SendMessageW(hStatic, WM_SETTEXT, 0, StrPtr("chars above '9' are not allowed"))
      return 0   ' bingo: we do NOT process this message

   elseif wParam=VK_TAB then   ' let's grab the tab key and move the focus
      Dim as Integer ctrlIndex=1
      if hWnd=hEdit(1) then ctrlIndex=2
      if hWnd=hEdit(2) then ctrlIndex=0
      SetFocus(hEdit(ctrlIndex))
      return 0   ' we don't want tabs in our edit boxes

   else
      SendMessageW(hStatic, WM_SETTEXT, 0, StrPtr("ok"))
   endif

  elseif uMsg=WM_KEYDOWN and wParam=VK_ESCAPE then   ' Escape is not a CHAR, so we need another message
   SendMessage(GetParent(hWnd), WM_CLOSE, 0, 0)   ' quit
  endif
  return CallWindowProc(PreviousWinProc, hWnd, uMsg, wParam, lParam) ' perform default processing
End Function

Function WndProc(hWnd As HWND, msg As UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
  Select Case msg
  Case WM_CTLCOLOREDIT   ' we colour the edit controls
   SetTextColor(wParam, Rgba(255, 255, 255, 0))
   SetBkMode(wParam, TRANSPARENT)
   Dim as Integer ctrlIndex=0
   if lParam=hEdit(1) then ctrlIndex=1
   if lParam=hEdit(2) then ctrlIndex=2
   return hBrush(ctrlIndex)
  Case WM_CREATE   ' we create two child controls here
     #define childwidth 285
   hStatic=CreateWindowEx(0, "static", "start typing now...",_
   WS_CHILD Or WS_VISIBLE, 3, 1, childwidth, 20, hWnd, 100, 0, 0)
   hEdit(0)=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", 0,_
   WS_CHILD Or WS_VISIBLE or ES_MULTILINE, 3, 22, childwidth, 30, hWnd, 101, 0, 0)
   PreviousWinProc=SetWindowLongPtr(hEdit(0), GWLP_WNDPROC, @SubEdit)
   hEdit(1)=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", 0,_
   WS_CHILD Or WS_VISIBLE or ES_MULTILINE, 3, 52, childwidth, 30, hWnd, 101, 0, 0)
   PreviousWinProc=SetWindowLongPtr(hEdit(1), GWLP_WNDPROC, @SubEdit)
   hEdit(2)=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", 0,_
   WS_CHILD Or WS_VISIBLE or ES_MULTILINE, 3, 82, childwidth, 30, hWnd, 101, 0, 0)
   PreviousWinProc=SetWindowLongPtr(hEdit(2), GWLP_WNDPROC, @SubEdit)
   hBrush(0)=CreateSolidBrush(Rgba(255, 160, 160, 0))
   hBrush(1)=CreateSolidBrush(Rgba(160, 255, 160, 0))
   hBrush(2)=CreateSolidBrush(Rgba(160, 160, 255, 0))
   SetFocus(hEdit(0))   ' start typing immediately
  Case WM_DESTROY
      PostQuitMessage(0)   ' close the main window
  End Select
  return DefWindowProc(hwnd, msg, wParam, lParam)
End Function

Function WinMain(hInstance As HINSTANCE, hPrevInstance As HINSTANCE, lpCmdLine As LPSTR, nShowCmd As Integer) As Integer
   Dim As WNDCLASSEX wc
   Dim As MSG msg
   Dim As string classname="FbGui"
   wc.cbSize = sizeof(WNDCLASSEX)
   wc.hbrBackground = COLOR_BTNFACE+1
   wc.hCursor = LoadCursor(0, IDC_ARROW)
   wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION)
   wc.hIconSm = wc.hIcon
   wc.hInstance = hInstance
   wc.lpfnWndProc = @WndProc
   wc.lpszClassName = StrPtr(classname)
   wc.style = CS_HREDRAW Or CS_VREDRAW
   RegisterClassEx(@wc)
   if CreateWindowEx(0, wc.lpszClassName, "Simple subclassing example",_
   WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX or WS_VISIBLE,_
   (GetSystemMetrics(SM_CXSCREEN) / 2) - 150,_
   (GetSystemMetrics(SM_CYSCREEN) / 2) - 100, 300, 140, 0, 0, hInstance, 0)=0 then
          MessageBox(0, "Creating hMain failed miserably", 0, MB_OK)
          return 0
   End If

   While GetMessage(@msg, 0, 0, 0)
      TranslateMessage(@msg)
      DispatchMessage(@msg)
   Wend

   return msg.wParam
End Function

' ----------- end of functions, the main program starts here: -----------
WinMain(GetModuleHandle(NULL), NULL, COMMAND(), SW_NORMAL)
RNBW
Posts: 192
Joined: Apr 11, 2015 11:06
Location: UK

Re: Simple example: Subclassing of an edit control

Postby RNBW » Sep 01, 2018 10:09

That's even more interesting, giving an idea how to deal with more than one edit control, including colouring the control. I'm going to be busy for the next week, but as soon as possible I'd like to have a good look at the code. The more examples we see, the more a pattern develops and everything will click into place.
Kwabbernoot
Posts: 73
Joined: Apr 19, 2010 18:23
Location: NL

Re: Simple example: Subclassing of an edit control

Postby Kwabbernoot » Sep 01, 2018 19:24

Instead of SetWindowLongPtr you can use the more modern: SetWindowSubclass
aurelVZAB
Posts: 291
Joined: Jul 02, 2008 14:55
Location: Croatia
Contact:

Re: Simple example: Subclassing of an edit control

Postby aurelVZAB » Sep 01, 2018 20:17

Hi JJ
Nice Example..
I don't know that you use FB ?

all best Aurel
jj2007
Posts: 1259
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Simple example: Subclassing of an edit control

Postby jj2007 » Sep 01, 2018 23:13

Kwabbernoot wrote:Instead of SetWindowLongPtr you can use the more modern: SetWindowSubclass
What is the advantage, apart from being "modern"?

@Aurel: Hi old friend, welcome to FB!
Josep Roca
Posts: 449
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Simple example: Subclassing of an edit control

Postby Josep Roca » Sep 01, 2018 23:17

> What is the advantage, apart from being "modern"?

https://docs.microsoft.com/en-us/window ... g-overview
jj2007
Posts: 1259
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Simple example: Subclassing of an edit control

Postby jj2007 » Sep 01, 2018 23:35

I know the link. What is the advantage, other than being a bit more complicated? Can you show me some examples of real world applications where you decided in the middle of the code to remove the old callback and replace it with another one, just for fun?

IMHO the main reason why Micros**t "modernised" the subclassing was that the new code ran only on XP - a marketing trick.

For the fans of 'modern' code, I've put together the above example using both variants in parallel (SubEdit6 is "modern"):

Code: Select all

#if 0   ' *** simple example how to subclass an edit control ***
  This example creates a Windows application with a static and three edit controls
  The edit controls are subclassed and do not accept anything above Ascii 57, i.e. the number 9
  The source consists of three major parts:
  - Function SubEdit5 is a callback procedure (added with SetWindowLongPtr) where we decide which keypresses to accept
  - same for Function SubEdit6, except that it uses the "modern" SetWindowSubclass(..) method
  - Function WndProc is the main window's callback procedure; here, we can handle various events
  - Function WinMain does the setup of the main window, and creates the message loop
  *** Note this is not an exhaustive example how to create a Windows GUI application; it just gives you the
  minimum skeleton to perform subclassing. You will get plenty of useless warnings - just ignore them ***
#endif
#include "windows.bi"
#include "win\commctrl.bi"
Dim Shared as Handle hEdit(2)
Dim Shared as Handle hBrush(2)
Dim Shared as Handle hStatic
Dim Shared as any ptr PreviousWinProc

Function SubEdit6(hWnd As HWND, uMsg As UINT, wParam As WPARAM, lParam As LPARAM, uIdSubclass As UINT_PTR, dwRefData As DWORD_PTR) As LRESULT
  ' we ignore all messages and pass them on to Windows via CallWindowProc, with one exception:
  ' if Windows tells us that it wants to pass a CHAR that we don't like, WE BLOCK IT:
  #if 0   ' under the hood...
   push ebp
   mov ebp, esp
   sub esp, 8
   push ebx
   push esi
   push edi
   mov dword ptr [ebp-4], 0
   int3
   mov eax, 6
  #endif
'   asm int 3
'   asm mov eax, 6
  if uMsg=WM_CHAR then   ' we are interested in the WM_CHAR message:

   if wParam>57 then
      SendMessageW(hStatic, WM_SETTEXT, 0, StrPtr("chars above '9' are not allowed"))
      return 0   ' bingo: we do NOT process this message

   elseif wParam=VK_TAB then   ' let's grab the tab key and move the focus
      Dim as Integer ctrlIndex=1
      if hWnd=hEdit(1) then ctrlIndex=2
      if hWnd=hEdit(2) then ctrlIndex=0
      SetFocus(hEdit(ctrlIndex))
      return 0   ' we don't want tabs in our edit boxes

   else
      SendMessageW(hStatic, WM_SETTEXT, 0, StrPtr("ok"))
   endif

  elseif uMsg=WM_KEYDOWN and wParam=VK_ESCAPE then   ' Escape is not a CHAR, so we need another message
   SendMessage(GetParent(hWnd), WM_CLOSE, 0, 0)   ' quit
  endif
  return DefSubclassProc(hWnd, uMsg, wParam, lParam) ' perform default processing
End Function

Function SubEdit5(hWnd As HWND, uMsg As UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
  ' we ignore all messages and pass them on to Windows via CallWindowProc, with one exception:
  ' if Windows tells us that it wants to pass a CHAR that we don't like, WE BLOCK IT:
  #if 0   ' under the hood...
   push ebp
   mov ebp, esp
   sub esp, 8
   push ebx
   push esi
   push edi
   mov dword ptr [ebp-4], 0
   int3
   mov eax, 5
  #endif
'   asm int 3
'   asm mov eax, 5
  if uMsg=WM_CHAR then   ' we are interested in the WM_CHAR message:

   if wParam>57 then
      SendMessageW(hStatic, WM_SETTEXT, 0, StrPtr("chars above '9' are not allowed"))
      return 0   ' bingo: we do NOT process this message

   elseif wParam=VK_TAB then   ' let's grab the tab key and move the focus
      Dim as Integer ctrlIndex=1
      if hWnd=hEdit(1) then ctrlIndex=2
      if hWnd=hEdit(2) then ctrlIndex=0
      SetFocus(hEdit(ctrlIndex))
      return 0   ' we don't want tabs in our edit boxes

   else
      ' SendMessageW(hStatic, WM_SETTEXT, 0, "ok")
      SendMessageW(hStatic, WM_SETTEXT, 0, StrPtr("ok"))
   endif

  elseif uMsg=WM_KEYDOWN and wParam=VK_ESCAPE then   ' Escape is not a CHAR, so we need another message
   SendMessage(GetParent(hWnd), WM_CLOSE, 0, 0)   ' quit
  endif
  return CallWindowProc(PreviousWinProc, hWnd, uMsg, wParam, lParam) ' perform default processing
End Function

Function WndProc(hWnd As HWND, msg As UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
  Select Case msg
  Case WM_CTLCOLOREDIT   ' we colour the edit controls
   SetTextColor(wParam, Rgba(255, 255, 255, 0))
   SetBkMode(wParam, TRANSPARENT)
   Dim as Integer ctrlIndex=0
   if lParam=hEdit(1) then ctrlIndex=1
   if lParam=hEdit(2) then ctrlIndex=2
   return hBrush(ctrlIndex)
  Case WM_CREATE   ' we create two child controls here
     #define childwidth 285
   hStatic=CreateWindowEx(0, "static", "start typing now...",_
   WS_CHILD Or WS_VISIBLE, 3, 1, childwidth, 20, hWnd, 100, 0, 0)
   hEdit(0)=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", 0,_
   WS_CHILD Or WS_VISIBLE or ES_MULTILINE, 3, 22, childwidth, 30, hWnd, 101, 0, 0)
   #if 1   ' modern stuff!!!!!!!!!!!!!
      SetWindowSubclass(hEdit(0), @SubEdit6, 11111, 22222)
   #else   ' old-fashioned
      PreviousWinProc=SetWindowLongPtr(hEdit(0), GWLP_WNDPROC, @SubEdit5)
   #endif
   hEdit(1)=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", 0,_
   WS_CHILD Or WS_VISIBLE or ES_MULTILINE, 3, 52, childwidth, 30, hWnd, 102, 0, 0)
   PreviousWinProc=SetWindowLongPtr(hEdit(1), GWLP_WNDPROC, @SubEdit5)
   hEdit(2)=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", 0,_
   WS_CHILD Or WS_VISIBLE or ES_MULTILINE, 3, 82, childwidth, 30, hWnd, 103, 0, 0)
   PreviousWinProc=SetWindowLongPtr(hEdit(2), GWLP_WNDPROC, @SubEdit5)
   hBrush(0)=CreateSolidBrush(Rgba(255, 160, 160, 0))
   hBrush(1)=CreateSolidBrush(Rgba(160, 255, 160, 0))
   hBrush(2)=CreateSolidBrush(Rgba(160, 160, 255, 0))
   SetFocus(hEdit(0))   ' start typing immediately
  Case WM_DESTROY
      PostQuitMessage(0)   ' close the main window
  End Select
  return DefWindowProc(hwnd, msg, wParam, lParam)
End Function

Function WinMain(hInstance As HINSTANCE, hPrevInstance As HINSTANCE, lpCmdLine As LPSTR, nShowCmd As Integer) As Integer
   Dim As WNDCLASSEX wc
   Dim As MSG msg
   Dim As string classname="FbGui"
   wc.cbSize = sizeof(WNDCLASSEX)
   wc.hbrBackground = COLOR_BTNFACE+1
   wc.hCursor = LoadCursor(0, IDC_ARROW)
   wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION)
   wc.hIconSm = wc.hIcon
   wc.hInstance = hInstance
   wc.lpfnWndProc = @WndProc
   wc.lpszClassName = StrPtr(classname)
   wc.style = CS_HREDRAW Or CS_VREDRAW
   RegisterClassEx(@wc)
   if CreateWindowEx(0, wc.lpszClassName, "Simple subclassing example",_
   WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_MINIMIZEBOX or WS_VISIBLE,_
   (GetSystemMetrics(SM_CXSCREEN) / 2) - 150,_
   (GetSystemMetrics(SM_CYSCREEN) / 2) - 100, 300, 140, 0, 0, hInstance, 0)=0 then
          MessageBox(0, "Creating hMain failed miserably", 0, MB_OK)
          return 0
   End If

   While GetMessage(@msg, 0, 0, 0)
      TranslateMessage(@msg)
      DispatchMessage(@msg)
   Wend

   return msg.wParam
End Function

' ----------- end of functions, the main program starts here: -----------
WinMain(GetModuleHandle(NULL), NULL, COMMAND(), SW_NORMAL)
Last edited by jj2007 on Sep 02, 2018 10:00, edited 1 time in total.
deltarho[1859]
Posts: 2072
Joined: Jan 02, 2017 0:34
Location: UK

Re: Simple example: Subclassing of an edit control

Postby deltarho[1859] » Sep 02, 2018 6:18

Nice piece of code, jj.

If a FreeBASIC newbie saw those 16 warnings they would say: "Oh, my" - or words to that effect. With '- w 2' we don't get any. <smile>
Josep Roca
Posts: 449
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Simple example: Subclassing of an edit control

Postby Josep Roca » Sep 02, 2018 7:19

See also: https://blogs.msdn.microsoft.com/oldnew ... /?p=41883/

BTW you aren't removing the subclass when the control is destroyed.
See: viewtopic.php?f=7&t=26816&p=251168&hilit=removewindowsubclass#p251166
Josep Roca
Posts: 449
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Simple example: Subclassing of an edit control

Postby Josep Roca » Sep 02, 2018 7:31

Other benefits is that if you use the same callback to subclass several controls you can easily identify which control is sending the messages, that you don't need to use globals to keep the addresses of the old windows procedures and that you can pass reference data.

BTW I don't think that any improvement in the Windows API is a Microsoft's conspiracy.
deltarho[1859]
Posts: 2072
Joined: Jan 02, 2017 0:34
Location: UK

Re: Simple example: Subclassing of an edit control

Postby deltarho[1859] » Sep 02, 2018 8:44

Josep Roca wrote:BTW you aren't removing the subclass when the control is destroyed.

I thought that too, as in RemoveWindowSubclass and have been using it.

However, at MSDN for SetWindowSubclass it says "To remove a subclass, pass the subclass procedure and this value to the RemoveWindowSubclass function. This value is passed to the subclass procedure in the uIdSubclass parameter." It uses the term 'Remove' and not 'Destroy' as with 'BCryptDestroyKey', where it says for BCryptGenerateSymmetricKey, "This handle must be released when it is no longer needed by passing it to the BCryptDestroyKey function."

So, my money is on no memory leak if we do not use RemoveWindowSubclass and it used when we want to turn off subclassing, for some reason, before the application closes.
BTW I don't think that any improvement in the Windows API is a Microsoft's conspiracy.

Neither do I.
jj2007
Posts: 1259
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Simple example: Subclassing of an edit control

Postby jj2007 » Sep 02, 2018 10:14

Josep Roca wrote:See also: https://blogs.msdn.microsoft.com/oldnew ... /?p=41883/

BTW you aren't removing the subclass when the control is destroyed.
See: viewtopic.php?f=7&t=26816&p=251168&hilit=removewindowsubclass#p251166
Josep Roca wrote:Other benefits is that if you use the same callback to subclass several controls you can easily identify which control is sending the messages, that you don't need to use globals to keep the addresses of the old windows procedures and that you can pass reference data.
You can test what happens without RemoveWindowSubclass by adding a line in the callbacks above (updated because the child IDs were wrong):

Code: Select all

   if wParam>57 then
      if wParam=100 then DestroyWindow(hWnd)
In both the SubEdit5 and SubEdit6 versions, nothing happens, the OS is tolerant. And of course, on exit you shouldn't do such acrobatics (Raymond Chen): The building is being demolished. Don't bother sweeping the floor and emptying the trash cans

Getting the ID is indeed a tick easier, but comparing hWnd to the available handles does the job, too.

So, in conclusion: Both methods work. If you plan to change, in the middle of your code, to another subclassproc, use the "modern" method.
Josep Roca
Posts: 449
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Simple example: Subclassing of an edit control

Postby Josep Roca » Sep 02, 2018 10:36

I make good use of the dwRefData parameter.

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 2 guests