I create an edit box as a child window control and I want to subclass it so that I can trap certain keyboard input and process it differently. I create the child edit box in my MainWndProc function in response to a WM_CREATE message. After I create it, I subclass it using the SetWindowLongPtr function. However, I immediately get a "Read access violation" error message in my new edit box procedure when it attempts to access the "message" variable. Here is the code:
!------------------------------------------------------------------------------
integer(LRESULT) function MainWndProc (hWnd, mesg, wParam, lParam)
!------------------------------------------------------------------------------
! Processes messages for the main window.
!------------------------------------------------------------------------------
---- Other specification statements ----
integer(LONG_PTR) ebptr
interface !Explicit interface to new edit box procedure
function EditBoxProc(hwnd, mesg, wParam, lParam)
use ifwinty
use user32
use TestButtonsglobals
integer(SINT) :: EditBoxProc
integer(HANDLE) hwnd
integer(UINT) mesg
integer(UINT_PTR) wParam
integer(LONG_PTR) lParam
end function EditBoxProc
end interface
----- Other statements -----
case (WM_CREATE)
hEdtW = CreateWindowEx(WS_EX_CLIENTEDGE, "Edit"C, ""C, style, 416, 46, EdtRW, TxtH, hWnd, 81, ghInstance, NULL)
ebptr = LOC(EditBoxProc)
hOrigEditBoxProc = SetWindowLongPtr(hEdtW, GWL_WNDPROC, ebptr) !Subclass default edit box procedure
----- Other statements -----
end function MainWndProc
!------------------------------------------------------------------------------
integer(SINT) function EditBoxProc (hWnd, mesg, wParam, lParam) !New edit box procedure
!------------------------------------------------------------------------------
use ifwinty
use user32
use TestButtonsGlobals !Holds handle for original edit box procedure and for main window
implicit none
integer(HANDLE) hWnd
integer(UINT) mesg
integer(UINT_PTR) wParam
integer(LONG_PTR) lParam
integer(LRESULT) j
!
!-----Process keyboard messages.
!
select case (mesg) !This is where the read access violation occurs
case (WM_KEYDOWN)
select case (wParam)
case (VK_TAB)
j = SendMessage(ghwndMain, mesg, wParam, lParam)
EditBoxProc = 1
return
end select
end select
EditBoxProc = CallWindowProc(hOrigEditBoxProc, hWnd, mesg, wParam, lParam) !Default processing
return
end function EditBoxProc
What am I doing wrong?
Thanks!
連結已複製
Thanks for the suggestion. I tried all possible combinations (integer*4, integer*8) for ebptr (the pointer to EditBoxProc) and for the definition of EditBoxProc, and in all cases I got the same "read access violation" exception.
Further clarification:
The call to SetWindowLongPtr executes successfully (the return value is non-null), and a subsequent call to GetWindowLongPtr verifies that the address of the new WndProc function for the edit box is ebptr. The read access violation occurs on some subsequent call to EdtBoxProc.
function BpatDlgProc( hDlg, message, uParam, lParam ) bind(C, name='BpatDlgProc')
!DEC$ ATTRIBUTES STDCALL :: BpatDlgProc
use ifwin, only: INT_PTR, HANDLE, UINT, fwparam, flparam
implicit none
integer(INT_PTR) :: BpatDlgProc
integer(HANDLE), intent(in), VALUE :: hDlg ! window handle of the dialog box
integer(UINT), intent(in), VALUE :: message ! type of message
integer(fwparam), intent(in), VALUE :: uParam ! message-specific information
integer(flparam), intent(in), VALUE :: lParam
Callbacks usually have a template that looks like the above. As Ian says you need STDCALL attribute
Andrew, Ian --
I placed the line
!DEC$ ATTRIBUTES STDCALL :: EditBoxProc
in my EditBoxProc function, and now I get a link error
Error LNK2019: unresolved external symbol _EditBoxProc@16 referenced in function _MainWndProc@16
Are there other lines I need to add? Do I need to add lines to my MainWndProc function?
Thanks!