Results 1 to 24 of 24

Thread: Persistent Debug Print Window

  1. #1

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,808

    Persistent Debug Print Window

    Ok, there's a fairly good Windows "built-in" option for this, discussed here.

    (Don't forget the Add-In companion for this program, found here.)

    However, I wanted a more pure VB6 solution. So, I came up with the following. Basically, it just gives you a DebugPrint procedure in any program you're developing, with the output being persistent across exits and re-loads of the VB6 IDE. Also, if you're developing something that's crashing your IDE, it will be persistent for that as well. Also, it can show you substantially more volume of information than the IDE's Immediate window. Also, it will work from a compiled program as well as from the IDE.

    It preserves the ability to use the comma (but not the semicolon) when printing debug information. For instance, the following are valid:

    DebugPrint "Test Point #1"
    DebugPrint "Var1:", Var1, "Var2:", Var2

    But this won't work:

    DebugPrint "Var1: "; Var1

    With respect to the actual PersistentDebugPrint program, you can either compile it and execute it, or you can just execute it from the IDE. It'll work either way.

    To use it, you just throw the DebugPrint.bas module into the program you're developing, and start making calls to the DebugPrint procedure.

    Warning: In the PersistentDebugPrint program, I store a handful of settings in the registry. If you look, it's obvious what I'm storing, but I know that this concerns some people, so this is just a heads-up that I'm doing this.

    Basically, here's all it is (from the Test program):

    Name:  DebugPrint.png
Views: 2774
Size:  8.7 KB

    Enjoy,
    Elroy

    Update #1: The class name for the DebugPrint window is a bit different when compiled versus running in the IDE, and I forgot to check for that. That's now fixed. I also added a DoDebugPrint constant to the DebugPrint.bas module so you can turn it all on/off without needing to comment out your DebugPrint lines.

    Update #2: I've actually tweaked on this thing quite a bit since I last updated it. Changes (I can remember):

    • There's now a "CodeForDebugPrint--->ToClipboard" menu option which allows you to quickly grab the new module code (modDebugPrint) for throwing into any project and use this thing.
    • There are tabs, so you can have different programs output debug info to separate tabs. To use them, there's a new DebugPrintToTab procedure in the modDebugPrint module. Here's the declaration:
      Code:
      Public Sub DebugPrintToTab(iTabNumber As Long, ParamArray vArgs() As Variant)
      Just specify the tab you wish to DebugPrint to as iTabNumber, starting with 1, and it'll do that. If the tab doesn't exist, tabs are opened in the PersistentDebugPrint program such that your tab does exist. An iTabNumber=0 prints out to whatever tab currently has the focus. Any negative value in iTabNumber prints out to the largest tab number currently open in PersistentDebugPrint. Thanks to Eduardo for the custom tab control. It's a modified and cut-down version of what he has here.
    • The actual output textbox has a context menu with most of the same stuff that's in the main menu. The "Clear" and "Separate" are only for the tab with the focus. Font, BackColor, & ForeColor are global. Making those per-tab might be a future update.
    • And just as an FYI, the older DebugPrint procedure (if you've got it in existing projects) will still work with this new program. It'll just output to whatever tab has the focus (as if iTabNumber=0).

    Here's a new screenshot:

    Name:  DebugPrint3.jpg
Views: 1538
Size:  22.4 KB

    Update #3: Fixed a bug in the modDebugPrint stub. The bug was that it only printed one line, now fixed.

    If you download it, it's best to just compile it immediately. I just place the EXE on my desktop as I use it frequently. And then, just click the new "CodeForDebugPrint--->ToClipboard" option, and paste that code into a new module of whatever project you like. To use it, just replace your Debug.Print statements with DebugPrint (no period, with caveats noted above). Or, alternatively, use DebugPrintToTab.

    Enjoy!
    Attached Files Attached Files
    Last edited by Elroy; Dec 24th, 2022 at 03:06 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  2. #2
    Fanatic Member
    Join Date
    Jun 2016
    Location
    España
    Posts
    594

    Re: Persistent Debug Print Window

    very good work, as additional data only works if the program works as an administrator.

    I could also put the path or name of the executable that sent the message in case there is more to differentiate

    a greeting

    sorry for using translator

  3. #3
    PowerPoster yereverluvinuncleber's Avatar
    Join Date
    Feb 2014
    Location
    Norfolk UK (inbred)
    Posts
    3,072

    Re: Persistent Debug Print Window

    Elroy, I love this addition to VB6 and it adding it to my Rocketdock Enhanced Settings utility was a real boon to debugging certain runtime issues.

    Do you have a VB.NET version? If not then I'll try and convert it myself.

  4. #4

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,808

    Re: Persistent Debug Print Window

    Quote Originally Posted by yereverluvinuncleber View Post
    Elroy, I love this addition to VB6 and it adding it to my Rocketdock Enhanced Settings utility was a real boon to debugging certain runtime issues.

    Do you have a VB.NET version? If not then I'll try and convert it myself.

    Nope, sorry. I'm not a netter. Good luck with the translation.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  5. #5
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,229

    Re: Persistent Debug Print Window

    I really like this thanks for sharing. couple possible ideas

    - when the exe runs have it savesetting its current path. The client can then auto start it on demand if not running yet
    - a <CLEAR> command so you can include a dbg.Clear to start fresh display from the code under debugging.
    - printf handler for easy formatting
    - topmost setting
    Last edited by dz32; Apr 22nd, 2020 at 09:57 AM.

  6. #6

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,808

    Re: Persistent Debug Print Window

    Hi dz32,

    Thanks for the compliment. However, truth be told, I doubt I'll find the motivation to do much more to this thing. But you've got the source code, and you're more than welcome to add the enhancements you'd like. Heck, I don't even mind if you post an enhanced version into this thread, or just fork it and make your own CodeBank thread.

    Take Care,
    Elroy
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  7. #7
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,229

    Re: Persistent Debug Print Window

    Sure happy to contribute.

    Mods:
    - Sub debugPrintf(ByVal msg As String, ParamArray values() As Variant)
    - Sub debugClear()
    - Sub debugDiv() 'divider
    - Sub debugPrint(ParamArray vArgs() As Variant) (pre-existing)
    - Settings -> TopMost
    - Settings -> Timestamp
    - debug client module can autostart the debug window server (exe) if its not running already
    (must have been started once though so it can save path to registry)

    The printf handler covers the basics:
    Code:
    'implements:
    '    \t -> tab
    '    \n -> vbcrlf
    '    %% -> %
    '    %x = hex
    '    %X = UCase(Hex(var))
    '    %s = string
    '    %S = UCase string
    '    %c = Chr(var)
    '    %d = numeric
    
    some printf examples from an old blog post:
        List1.AddItem printf("number 0x%x", 16)
        List1.AddItem printf("number %08x", &HCC)
        List1.AddItem printf("number %8X", &HCC)
        List1.AddItem printf("this is %s and can also be %S", "my string", "upper case")
        List1.AddItem printf("%s", "string with no prefix")
        List1.AddItem printf("0xCC in decimal = %d", &HCC)
        List1.AddItem printf("chr(&h41) = %c", &H41)
        List1.AddItem printf("chr(&h41) = %c it is my %s", &H41, "favorite letter")
    
    output:
        number 0x10
        number 000000CC
        number       CC
        this is my string and can also be UPPER CASE
        string with no prefix
        0xCC in decimal = 204
        chr(&h41) = A
        chr(&h41) = A it is my favorite letter
    Last edited by dz32; Apr 22nd, 2020 at 08:15 PM.

  8. #8
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,229

    Re: Persistent Debug Print Window

    one more addition, just in case the vb process is running as admin

    Code:
    Private Declare Function ChangeWindowMessageFilter Lib "user32" (ByVal msg As Long, ByVal flag As Long) As Long 'Vista+
    Const WM_COPYDATA = &H4A
    Const WM_COPYGLOBALDATA = &H49
    
    Public Function AllowCopyDataAcrossUIPI()
        Dim a, b, c
        Const MSGFLT_ADD = 1
        'a = ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD)
        b = ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD) 
        c = ChangeWindowMessageFilter(WM_COPYGLOBALDATA, MSGFLT_ADD)
        'MsgBox a & " " & b & " " & c
    End Function
    and a sample C client

    Code:
    #include <Windows.h>
    #include <stdio.h>
    #include <conio.h>
    
    void msg(char);
    void msgf(const char*, ...);
    
    bool Warned=false;
    HWND hServer=0;
    
    HWND regFindWindow(void){
    
             // SaveSetting "dbgWindow", "settings", "hwnd", Me.hWnd
    	 char* baseKey = "Software\\VB and VBA Program Settings\\dbgWindow\\settings";
    	 char tmp[20] = {0};
         unsigned long l = sizeof(tmp);
    	 HWND ret=0;
    	 HKEY h;
    	 
    	 printf("regFindWindow triggered\n");
    
    	 RegOpenKeyExA(HKEY_CURRENT_USER, baseKey, 0, KEY_READ, &h);
    	 RegQueryValueExA(h, "hwnd", 0,0, (unsigned char*)tmp, &l);
    	 RegCloseKey(h);
    	
    	 ret = (HWND)atoi(tmp);
    	 if(!IsWindow(ret)) ret = 0;
    	 return ret;
    }
    
    void FindVBWindow(){
    	char *vbIDEClassName = "ThunderFormDC" ;
    	char *vbEXEClassName = "ThunderRT6FormDC" ;
    	char *vbEXEClassName2 = "ThunderRT6Form" ;
    	char *vbWindowCaption = "Persistent Debug Print Window" ;
    
    	hServer = FindWindowA( vbIDEClassName, vbWindowCaption );
    	if(hServer==0) hServer = FindWindowA( vbEXEClassName, vbWindowCaption );
    	if(hServer==0) hServer = FindWindowA( vbEXEClassName2, vbWindowCaption );
    	if(hServer==0) hServer = regFindWindow(); //if ide is running as admin
    
    	if(hServer==0){
    		if(!Warned){
    			//MessageBox(0,"Could not find msg window","",0);
    			printf("Could not find msg window\n");
    			Warned=true;
    		}
    	}
    	else{
    		if(!Warned){
    			//first time we are being called we could do stuff here...
    			printf("hServer = %x\n", hServer);
    			Warned=true;
    
    		}
    	}	
    
    } 
    
    int msg(char *Buffer){
      
      if(!IsWindow(hServer)) hServer=0;
      if(hServer==0) FindVBWindow();
      
      COPYDATASTRUCT cpStructData;
      memset(&cpStructData,0, sizeof(struct tagCOPYDATASTRUCT )) ;
      
      //_snprintf(msgbuf, 0x1000, "%x,%x,%s", myPID, GetCurrentThreadId(), Buffer);
    
      cpStructData.dwData = 3;
      cpStructData.cbData = strlen(Buffer) ;
      cpStructData.lpData = (void*)Buffer;
      int ret = SendMessage(hServer, WM_COPYDATA, 0,(LPARAM)&cpStructData);
      return ret; //log ui can send us a response msg to trigger special reaction in ret
    
    } 
    
    void msgf(const char *format, ...)
    {
    	DWORD dwErr = GetLastError();
    		
    	if(format){
    		char buf[1024]; 
    		va_list args; 
    		va_start(args,format); 
    		try{
     			 _vsnprintf(buf,1024,format,args);
    			 msg(buf);
    		}
    		catch(...){}
    	}
    
    	SetLastError(dwErr);
    }
    
    void main(void){
    
    	msg("this is my test");
    	msgf("this is test %d", 2);
    	getch();
    
    }
    Last edited by dz32; Feb 22nd, 2022 at 10:40 AM.

  9. #9

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,808

    Re: Persistent Debug Print Window

    I had posted an update here, but please see the OP for the latest.
    Last edited by Elroy; Dec 23rd, 2022 at 07:11 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  10. #10
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,229

    Re: Persistent Debug Print Window

    had an idea on this today, I tend to use this for the worst debugging situations
    sometimes when you are dumping a lot of info to the debug window info can get interspersed
    like high level outer loop then a bunch of inner loop messages making it hard to digest the outerloop

    Similar to the concept of log levels (info messages, warnings, critical etc.)

    I am thinking of being able to add tabs on demand from the debugee for different message levels
    or maybe just log levels is fine with a filter capability on the main textbox. humm...I guess a filter textbox
    control will do

    in other news I merged the tricks replace debug.print with a copy of this in a single class so you can
    enable/disable the redirection on demand. could still use a couple cleanups but working

    https://github.com/dzzie/libs/blob/m...rintSample.cls
    Last edited by dz32; Dec 21st, 2022 at 06:34 AM.

  11. #11

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,808

    Re: Persistent Debug Print Window

    Ahhh, I like the idea of tabs on the PersistentDebug window. I'll make that improvement today.

    I looked into The Trick's work on redirecting Debug.Print. What he did works, but it still has two problems to be useful for this project: 1) It just sends it to an object that can handle the .Print method (and you still can't capture the text), and 2) When compiled, Debug.Print goes away, so it's not useful for compiled programs which is where I often find PersistentDebug particularly useful. I'm just going to work it out another way.

    But again, I'll add tabs today.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  12. #12
    Fanatic Member
    Join Date
    Jun 2016
    Location
    España
    Posts
    594

    Re: Persistent Debug Print Window

    I use it every day.
    And I add some simple tabs.
    I send PropertyBag and in property I send the name of the group.
    Thank you very much Elroy for this utility

  13. #13
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,229

    Re: Persistent Debug Print Window

    so I think the most natural place for that single class debug.print redirector to live is actually with it hosted in an addin.

    I have a couple addins always loaded, so I just added an extra checkbox to one of the forms to enable/disable it on demand. (always off by default for stability)

    this way it doesnt have to be added to every project you might want to use it from and then add code to turn it on and off
    its just always ready to use with a simple toggle.

    added it to my fastbuild addin

    https://github.com/dzzie/addins/tree/master/FastBuild

  14. #14

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,808

    Re: Persistent Debug Print Window

    Yeah, I've thought about doing it as an add-in, but it doesn't quite work as one. For one, which piece are we talking about as an add-in: The "send" piece or the "receive/report" piece? If we put the "send" piece there, then it won't work when the program is compiled ... and I often use it that way. If we put the "receive/report" piece there, if the IDE crashes (which is a big part of this), it won't be persistent.

    I've just about got my "tabs" version finished and hope to post it later today.

    I've pretty much gotten it all worked out, but I'm certainly open to suggestions as to how tabs should work. Here's the way I've got it:

    * The tabs just have numbers for the tab-captions, starting with 1.
    * If zero-tab is specified by the "sending" program, the tab with the focus will be used.
    * If a tab number larger than 1 is specified, tabs will be added by the receiving/printing program up to the specified tab-number.
    * If -1 (or any negative tab#) is specified, the largest (already opened) tab will be used.
    * You can delete tabs from the reporting program, but only the last one. The first tab (#1) can never be deleted.
    * There's already a "Clear" menu option, which will clear the tab with the focus. There will also be a new "Clear All" option which will clear and delete all tabs (leaving only a blank #1 tab).

    Again, I should have it out here for y'all to examine later today.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  15. #15
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,229

    Re: Persistent Debug Print Window

    I added tricks debug.print redirector into the addin
    Which has been enhanced with your remote debug out sender

    So whatever project your working on you just use the normal
    Debug.print as always, no extra classes to include.

    If you want to redirect all normal debug.print messages to the remote Persistent debug window, just go to the addin config form and click enable And the rest works magically behind the scenes

    The remote debug receiver window is still a standalone process. I added an extra button to easily launch it from the ide as well
    Last edited by dz32; Dec 22nd, 2022 at 10:15 AM.

  16. #16
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,229

    Re: Persistent Debug Print Window

    I didn’t fully flesh out the idea of tabs. I was thinking of sending a control message like

    Inittabs:tab1:tab2

    Which the receiver would then parse and configure itself for.
    Then any message that started with tab1: would be redirected to the proper tab with the control part of the message stripped

    But that just lead me to the filter text box idea since i am basically just filtering based on message text then I could search for anything plus see all the messages in order still if I wanted and it would be very simple to code.

    A copy of it with the filter concept is in the dbgwindow sub folder of above project

  17. #17

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,808

    Re: Persistent Debug Print Window

    Quote Originally Posted by dz32 View Post
    I didn’t fully flesh out the idea of tabs. I was thinking of sending a control message like

    Inittabs:tab1:tab2
    Ohh, I've got the LPARAM I can use to send a number through, and I'm just using a new DebugPrintToTab(TheTab As Long, ParamArray ...) to specify which tab it's to go to. I'll just stuff that TheTab arg into LPARAM.

    EDIT: It's actually wParam. lParam is used for a pointer to the incoming structure which holds the text message.
    Last edited by Elroy; Dec 22nd, 2022 at 04:17 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  18. #18
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,229

    Re: Persistent Debug Print Window

    That’s a good solution

  19. #19

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,808

    Re: Persistent Debug Print Window

    Updated, see post #1.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  20. #20

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,808

    Re: Persistent Debug Print Window

    Notice: There was a bug in the modDebugPrint piece that I posted yesterday. So, if you grabbed it yesterday, you'll need to re-grab it.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  21. #21
    Fanatic Member
    Join Date
    Aug 2011
    Location
    Palm Coast, FL
    Posts
    689

    Re: Persistent Debug Print Window

    Suggestions for a future enhancement: Support for unicode.

  22. #22

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,808

    Re: Persistent Debug Print Window

    Quote Originally Posted by AAraya View Post
    Suggestions for a future enhancement: Support for unicode.

    hahaha, it's still the same me whether it's posted here or in the other thread.

    You've now got a clipboard option which isn't too bad, and it's also persistent.

    I'll eventually add Unicode support. It's just a bit involved (as outlined in the other thread), but I'll get to it someday.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  23. #23
    Fanatic Member
    Join Date
    Aug 2011
    Location
    Palm Coast, FL
    Posts
    689

    Re: Persistent Debug Print Window

    Just trying to keep the conversations organized with all relevant points made in their appropriate threads.

    I know it helps me when I come back to things in the future.

  24. #24
    Frenzied Member
    Join Date
    Jun 2015
    Posts
    1,229

    Re: Persistent Debug Print Window

    kind of a niche case but, with some small changes the debuggee sending messages to the debug print window can actually request config values to determine on the fly what behaviors to enable.

    use case, debugging complex dll where you might want to enable debug messages or certain features on the fly.
    dll sends message to print window to load a certain profile (ini of config settings)
    dll requests the config values
    acts differently without having to recompile the dll everytime.

    basic change just use sendmessage vrs sendmessagetimeout and return a long value. Some special debug print messages are taken as commands.

    I suppose the dll could just load the ini on its own, but then I would have had to program that part in C in a big complex project ;-\ Im lazy.
    Last edited by dz32; May 9th, 2025 at 12:29 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width