FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Ctrl + Alt + Click on a Control → Show ProcName() / ProcLine() for Support
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Ctrl + Alt + Click on a Control → Show ProcName() / ProcLine() for Support
Posted: Tue Dec 30, 2025 10:43 AM

Hello friends,

I’d like to share a small but very practical idea that could greatly simplify support and debugging in FiveWin/Harbour applications.

The idea
Add a support-only feature at the control or base class level:
Hold a key combination (e.g. Ctrl + Alt)
Click on any control
A MsgInfo() pops up showing where you are in the code:
MsgInfo( ProcName() + " " + Str( ProcLine() ) )

Optionally, the dialog could also show:
Class name
Control name
Window title

How it would work (conceptually)
The logic can be placed centrally, for example in a base class like TControl or TWindow:
Detect a key combination:
GetKeyState( VK_CONTROL ) .AND. GetKeyState( VK_MENU ) // Alt
Intercept the mouse click (LButtonDown, bLClicked, or HandleEvent).
If the support key combo is active, show the info and skip normal processing.
Why this is extremely useful for support
When a customer calls support, instead of saying
“I clicked somewhere on the screen…”

you can say:
“Please hold Ctrl + Alt and click on the field.”
The customer reads out something like:
EDITCUSTOMER 1234

And the support developer immediately knows:
the PRG
the exact line number
the class / control involved
No screenshots, no guessing, no back-and-forth.
Safety / production use
This can be made completely optional and safe:

Enabled only in support mode
Enabled only for certain users
Enabled only if a flag or INI file exists
When disabled, the application behaves exactly as before.
Summary
100 % doable
Clean to implement at class level
No impact on business logic
Huge benefit for real-world support

I’d be very interested to hear if others have implemented something similar—or what you think about this approach.

Best regards,
Otto

Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Re: Ctrl + Alt + Click on a Control → Show ProcName() / ProcLine() for Support
Posted: Tue Dec 30, 2025 06:04 PM

Hello friends,

I’ve taken a closer look at the possibilities. I think the key lies in this question from 2009 — I already wanted to do this back then:

https://forums.fivetechsupport.com/viewtopic.php?p=92446&hilit=WndHandleEvent#p92446

I believe that would be the best place for it.

Best regards,
Otto

Posts: 1286
Joined: Mon Feb 25, 2008 02:54 PM
Re: Ctrl + Alt + Click on a Control → Show ProcName() / ProcLine() for Support
Posted: Tue Dec 30, 2025 06:10 PM

Hello Otto,

I use something similar, CTRL+F1:

/*****************************************************************************/
procedure HelpIndex()
/

*/
Local aCallStack

if !GetKeyState( VK_CONTROL )
return
endif

aCallStack := GetCallStack(1)

Browse(aCallStack )

return

/*****************************************************************************/
static function GetCallStack( nBase )
/

*/
local aCallStack, nPos, hTemp

Default(@nBase, 0)

nPos := nBase + 1
aCallStack := {}

do while !Empty(ProcName(nPos))
hTemp := { 'cFuncao' => Lower(ProcName(nPos)),;
'nLinha' => ProcLine(nPos) ,;
'cArquivo' => ProcFile(nPos) }

hb_hAutoAdd(hTemp, .f.)
hb_hCaseMatch(hTemp, .t.)

AADD(aCallStack, hTemp)

nPos ++
enddo

return aCallStack

ubiratanmga@gmail.com

FWH24.04
BCC7.3
HARBOUR3.2
xMate
Pelles´C
TDolphin
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Re: Ctrl + Alt + Click on a Control → Show ProcName() / ProcLine() for Support
Posted: Tue Dec 30, 2025 11:16 PM

Dear Antonio,

I spent quite some time again today trying to get a reliable “where am I in the source code?” indicator at runtime (control + procedure + line), triggered by a mouse click or key.

After digging deeper, my current conclusion is this:

If we had access to a global, overridable WndHandleEvent( Self, nMsg, nWParam, nLParam ), the problem would be trivial. One central hook, full stack still alive, all controls covered.

However, WndHandleEvent() seems to be purely internal to FiveWin (C-level / non-exported). Because of that, events do not bubble through a single, user-accessible point.

As a result:

Window-level hooks do not reliably see button clicks

Control-level hooks are often too late

Buttons (TBUTTON, TBTNBMP, TRBTN, etc.) consume the event inside their own classes

So the only technically correct solution left is: handle this class by class, intercepting the event before the action is executed.

This works, but it means touching several classes instead of having one clean central hook.

Thanks to MGA for the call-stack code – it definitely helps to understand the execution path. However, it still does not give a precise “this is the exact source location” answer in all cases, especially once the framework has already taken over the event flow.

At this point it looks like a design limitation, not a missing trick.

Best regards Otto

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Ctrl + Alt + Click on a Control → Show ProcName() / ProcLine() for Support
Posted: Wed Dec 31, 2025 10:39 AM

Answer

You're asking about where to implement a "hook" for WndHandleEvent() that would allow users to specify particular events to route to the hook<cite />.

Event Handling System Location

The FiveWin event handling system centers around the WNDHANDLEEVENT function in C and the HandleEvent() method in Harbour classes 1-cite-0 . This function receives Windows messages and dispatches them to specific class methods<cite />.

Hook Implementation Options

Option 1: Window-Level Hook (Recommended)

The most direct approach would be to add a data member like bOnEvent in the TWindow class to intercept events before standard processing<cite />:

Code (harbour): Select all Collapse
CLASS TWindow
   DATA bOnEvent  // Codeblock hook for custom events

Then modify the HandleEvent() method to check this hook first 1-cite-1 :

Code (harbour): Select all Collapse
METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TWindow
   local uResult
   
   // Check for custom hook
   if ValType( ::bOnEvent ) == "B"
      uResult := Eval( ::bOnEvent, Self, nMsg, nWParam, nLParam )
      if uResult != nil
         return uResult  // Hook handled the event
      endif
   endif
   
   // Continue with normal processing...

Option 2: Hook in the C Function _FWH

You could modify the _FWH() function which is the entry point from the Windows window procedure 1-cite-1 . This function calls the window object's HandleEvent() 1-cite-2 .

Option 3: Specific Event Type Hook

In WNDHANDLEEVENT (the C function), you could add a mechanism to check for a hook before dispatching each specific message type 1-cite-3 . For example, before the switch(wMsg), check if a hook is registered for that message.

Suggested Practical Implementation

The cleanest implementation would be in the TWindow or TControl class, adding:

  1. A data member for the hook: DATA bEventHook
  2. A method to register the hook: METHOD SetEventHook( nMsg, bAction )
  3. Modify HandleEvent() to check the hook before standard processing

Usage example:

Code (harbour): Select all Collapse
oWnd:SetEventHook( WM_MOUSEMOVE, {|oWnd, nMsg, nWParam, nLParam| ;
   MsgInfo("Mouse moved!"), nil } )

Notes

The current system already has a similar pattern with codeblocks like bLButtonDown, bRButtonDown, etc. in control classes<cite />. A generic hook would follow this same pattern but allow intercepting any Windows message, not just predefined ones<cite />. The DialogWndProc function in ffdlgprc.c shows how HandleEvent is called from the C level 1-cite-4 , which would be another possible interception point but would require modifying C code.

Wiki pages you might want to explore:

Citations

File: source/classes/window.prg (L3760-3777)

Code (text): Select all Collapse
function _FWH( hWnd, nMsg, nWParam, nLParam, nAt )

   local oWnd

   static aRet := { 0, 0 }

   ( hWnd )

   if nAt != 0
      oWnd = aWindows[ nAt ]
      if ValType( oWnd ) == "O"
         aRet[ 1 ] = oWnd:HandleEvent( nMsg, nWParam, nLParam )
         aRet[ 2 ] = oWnd:nOldProc
      endif
      return aRet
   endif

return nil
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Re: Ctrl + Alt + Click on a Control → Show ProcName() / ProcLine() for Support
Posted: Wed Dec 31, 2025 10:55 AM

Dear Antonio,

Yes, that is correct in principle — FiveWin does have a central HandleEvent() path at the architectural level.

However, my own tests showed that in practice this path is not consistently reached by modern controls. In particular, buttons and Ribbon/Metro-style controls often shortcut the window-level dispatch and handle mouse events inside their own classes.

Because of that, a single, reliable global hook is not achievable with the framework as it is today. Implementing such a hook would require touching multiple control classes or modifying C-level code, which makes it impractical for real-world projects.

Best regards, Otto

Continue the discussion