• Login
sketchucation logo sketchucation
  • Login
ℹ️ GoFundMe | Our friend Gus Robatto needs some help in a challenging time Learn More

[Code] Win32 - Get SketchUp Window Handle (WIP)

Scheduled Pinned Locked Moved Developers' Forum
40 Posts 5 Posters 10.1k Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    thomthom
    last edited by 27 Dec 2010, 18:59

    Here's a snippet to get the handle for the SketchUp window the calling ruby script belongs to.

    <span class="syntaxdefault"><br />  GA_ROOTOWNER </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> 3<br /><br />  </span><span class="syntaxcomment"># Returns the window handle of the SketchUp window for the input queue of the<br /></span><span class="syntaxdefault">  </span><span class="syntaxcomment"># calling ruby method.<br /></span><span class="syntaxdefault">  </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault">  </span><span class="syntaxcomment"># @return [Integer] Returns a window handle on success or +nil+ on failure<br /></span><span class="syntaxdefault">  def self</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">get_sketchup_window<br />    </span><span class="syntaxcomment"># Retrieves the window handle to the active window attached to the calling<br /></span><span class="syntaxdefault">    </span><span class="syntaxcomment"># thread's message queue. <br /></span><span class="syntaxdefault">    hwnd </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> GetActiveWindow</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call<br />    return nil if hwnd</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">nil</span><span class="syntaxkeyword">?<br /></span><span class="syntaxdefault">    </span><span class="syntaxcomment"># In case the SketchUp window was not the active one - get the ancestor.<br /></span><span class="syntaxdefault">    GetAncestor</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">hwnd</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> GA_ROOTOWNER</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">  end<br /></span>
    

    (EDIT: This method will fail if the SketchUp window isn't the active window.)
    Alternative safer method here: http://forums.sketchucation.com/viewtopic.php?f=180&t=33756&start=15#p297228

    Thomas Thomassen — SketchUp Monkey & Coding addict
    List of my plugins and link to the CookieWare fund

    1 Reply Last reply Reply Quote 0
    • D Offline
      Dan Rathbun
      last edited by 27 Dec 2010, 19:12

      Does this work if wxSU is loaded ?? (wxSU creates a toplevel invisible sxWindow and makes Sketchup a child window of it. So Sketchup is no longer the toplevel window.)

      I'm not here much anymore.

      1 Reply Last reply Reply Quote 0
      • T Offline
        thomthom
        last edited by 28 Dec 2010, 00:10

        It does?
        ugh... I really don't know...
        In that case I suppose one need to travel each owner until you find one which matches some properties. Not sure if window text is the most reliable as webdialog might have "SketchUp" in it. Maybe by class...?

        Seems that wxSU has a number of issues under SU...

        Thomas Thomassen — SketchUp Monkey & Coding addict
        List of my plugins and link to the CookieWare fund

        1 Reply Last reply Reply Quote 0
        • T Offline
          thomthom
          last edited by 28 Dec 2010, 12:01

          Further testing: the method will fail if the SketchUp window isn't the active window.

          Thomas Thomassen — SketchUp Monkey & Coding addict
          List of my plugins and link to the CookieWare fund

          1 Reply Last reply Reply Quote 0
          • H Offline
            honoluludesktop
            last edited by 28 Dec 2010, 21:34

            Handle is a term I recall from my "good old DOS days" :-) Can the "SketchUp Window Handle" be used to close an instance of SketchUp from another instance of SketchUp?

            1 Reply Last reply Reply Quote 0
            • D Offline
              Dan Rathbun
              last edited by 28 Dec 2010, 23:24

              @honoluludesktop said:

              Handle is a term I recall from my "good old DOS days" :-) Can the "SketchUp Window Handle" be used to close an instance of SketchUp from another instance of SketchUp?

              Yes ... BUT ... we must first solve the issue of getting the CORRECT handle for each instance, and storing it (in the proper place,) where it can be accessed by multiple plugins.
              Once the "handle" is determined, the code that was needed to find it, is no longer needed, and should be garbage collected.

              THEN ... you'll need to solve the issue of talking between two instances of Sketchup Ruby, and having one inform the other what it's window handle is.

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • T Offline
                thomthom
                last edited by 29 Dec 2010, 00:55

                GetActiveWindow
                http://msdn.microsoft.com/en-us/library/ms646292%28v=vs.85%29.aspx

                @unknownuser said:

                The return value is the handle to the active window attached to the calling thread's message queue. Otherwise, the return value is NULL.

                What is interesting with this function is that it find a window based on the calling thread. But it's limitation is that it requires one of the windows that belong to the thread to the the active one.

                But, I'm trying to find a function that either let you enumerate the windows that belong to a thread, or get the top most window for a thread. In either one of those conditions one should be able to reliably get the window handle.

                I think one can get lots of useful info if one can get the thread id of the SketchUp process. Any ideas of how one can do this. I've been scanning the Win32 API a bit today looking for relevant functions.

                Thomas Thomassen — SketchUp Monkey & Coding addict
                List of my plugins and link to the CookieWare fund

                1 Reply Last reply Reply Quote 0
                • T Offline
                  thomthom
                  last edited by 29 Dec 2010, 01:22

                  @jim said:

                  I am not entirely sure the Win32API.so file we all have been using supports callbacks, which the windows enumerator functions require as arguments.

                  Specifically, calls to EnumWindows and EnumChildWindows can not be used with Win32API.

                  The win32-api ruby library does support callbacks, and we should really be using that it anyway. it's more robust, and more stable (I've read.)

                  I was just looking at this. I noticed the lack of Callback.
                  Where is the win32-api found - the one that supports callbacks?

                  Thomas Thomassen — SketchUp Monkey & Coding addict
                  List of my plugins and link to the CookieWare fund

                  1 Reply Last reply Reply Quote 0
                  • J Offline
                    Jim
                    last edited by 29 Dec 2010, 01:26

                    @thomthom said:

                    Where is the win32-api found - the one that supports callbacks?

                    http://win32utils.rubyforge.org/

                    I'm not sure if this can co-exist with Win32API or not.

                    require 'win32/api'

                    win32.zip

                    Hi

                    1 Reply Last reply Reply Quote 0
                    • J Offline
                      Jim
                      last edited by 29 Dec 2010, 01:26

                      I am not entirely sure the Win32API.so file we all have been using supports callbacks, which the windows enumerator functions require as arguments.

                      Specifically, calls to EnumWindows and EnumChildWindows can not be used with Win32API.

                      The win32-api ruby library does support callbacks, and we should really be using it anyway. it's more robust, and more stable (I've read.)

                      Hi

                      1 Reply Last reply Reply Quote 0
                      • T Offline
                        thomthom
                        last edited by 29 Dec 2010, 02:05

                        The example I saw of it:
                        http://stackoverflow.com/questions/3327666/win32s-findwindow-can-find-a-particular-window-with-the-exact-title-but-what/3328209#3328209

                        Seemed to use namespace Win32 as oppose to Win32API.

                        So this is not a module that ships with Ruby?

                        Thomas Thomassen — SketchUp Monkey & Coding addict
                        List of my plugins and link to the CookieWare fund

                        1 Reply Last reply Reply Quote 0
                        • D Offline
                          Dan Rathbun
                          last edited by 29 Dec 2010, 02:12

                          @thomthom said:

                          So this is not a module that ships with Ruby?

                          Correct... no it's not, because it is platform specific, AND considered an extension. You, or any user must download it from RubyForge. If you want the latest releases, as they are released. I believe you also must compile them yourself, or wait until Mr. Berger & Co decides to do it.

                          I'm not here much anymore.

                          1 Reply Last reply Reply Quote 0
                          • D Offline
                            Dan Rathbun
                            last edited by 29 Dec 2010, 02:32

                            @thomthom said:

                            win32-api Seemed to use namespace Win32 as oppose to Win32API.

                            True it has it's own namespace... and another quirk.. Dan Berger reordered the arguments in the API calls making it a bit cumbersome to have scripts that can use either library.

                            I'm not here much anymore.

                            1 Reply Last reply Reply Quote 0
                            • D Offline
                              Dan Rathbun
                              last edited by 29 Dec 2010, 02:58

                              @jim said:

                              I am not entirely sure the Win32API.so file we all have been using supports callbacks, which the windows enumerator functions require as arguments. ...
                              Specifically, calls to EnumWindows and EnumChildWindows can not be used with Win32API.

                              Actually Win32API.so is obsolete, and for some time, they have been suggesting coders migrate to using the DL library directly.

                              In Ruby vers 1.9.x and up... they no longer supply a Win32API.so file, instead they have replaced it with a Win32API.rb script that mimics the old so file, and translates Win32API calls into DL library calls.

                              This is the Win32API.rb file distro'd with Ruby v 1.9.1 p429

                              <span class="syntaxdefault"></span><span class="syntaxcomment"># -*- ruby -*-<br /># for backward compatibility<br /></span><span class="syntaxdefault">warn </span><span class="syntaxstring">"Warning;#{caller[0].sub(/;in `.*'\z/, '')}; Win32API is deprecated after Ruby 1.9.1; use dl directly instead"</span><span class="syntaxdefault"> if $VERBOSE<br /><br />require </span><span class="syntaxstring">'dl'<br /><br /></span><span class="syntaxdefault">class Win32API<br />  DLL </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{}<br /></span><span class="syntaxdefault">  TYPEMAP </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{</span><span class="syntaxstring">"0"</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">=></span><span class="syntaxdefault"> DL</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">TYPE_VOID</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"S"</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">=></span><span class="syntaxdefault"> DL</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">TYPE_VOIDP</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"I"</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">=></span><span class="syntaxdefault"> DL</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">TYPE_LONG</span><span class="syntaxkeyword">}<br /><br /></span><span class="syntaxdefault">  def initialize</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">dllname</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> func</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> import</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> export </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">"0"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">*</span><span class="syntaxdefault">rest</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">    </span><span class="syntaxkeyword">@</span><span class="syntaxdefault">proto </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">[</span><span class="syntaxdefault">import</span><span class="syntaxkeyword">].</span><span class="syntaxdefault">join</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">tr</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"VPpNnLlIi"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"0SSI"</span><span class="syntaxkeyword">).</span><span class="syntaxdefault">sub</span><span class="syntaxkeyword">(/^(.)</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">*$/,</span><span class="syntaxdefault"> </span><span class="syntaxstring">'\1'</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">    handle </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> DLL</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">dllname</span><span class="syntaxkeyword">]</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">||=</span><span class="syntaxdefault"> DL</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">dlopen</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">dllname</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">    </span><span class="syntaxkeyword">@</span><span class="syntaxdefault">func </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> DL</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">CFunc</span><span class="syntaxkeyword">.new(</span><span class="syntaxdefault">handle</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">func</span><span class="syntaxkeyword">],</span><span class="syntaxdefault"> TYPEMAP</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">export</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">tr</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"VPpNnLlIi"</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxstring">"0SSI"</span><span class="syntaxkeyword">)],</span><span class="syntaxdefault"> func</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">*</span><span class="syntaxdefault">rest</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">  end<br /><br />  def call</span><span class="syntaxkeyword">(*</span><span class="syntaxdefault">args</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">    import </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">@</span><span class="syntaxdefault">proto</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">split</span><span class="syntaxkeyword">(</span><span class="syntaxstring">""</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">    args</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each_with_index do </span><span class="syntaxkeyword">|</span><span class="syntaxdefault">x</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> i</span><span class="syntaxkeyword">|<br /></span><span class="syntaxdefault">      args</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">],</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">[</span><span class="syntaxdefault">x </span><span class="syntaxkeyword">==</span><span class="syntaxdefault"> 0 </span><span class="syntaxkeyword">?</span><span class="syntaxdefault"> nil </span><span class="syntaxkeyword">;</span><span class="syntaxdefault"> x</span><span class="syntaxkeyword">].</span><span class="syntaxdefault">pack</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"p"</span><span class="syntaxkeyword">).</span><span class="syntaxdefault">unpack</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"l!*"</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> if import</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">]</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">==</span><span class="syntaxdefault"> </span><span class="syntaxstring">"S"<br /></span><span class="syntaxdefault">      args</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">],</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">[</span><span class="syntaxdefault">x</span><span class="syntaxkeyword">].</span><span class="syntaxdefault">pack</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"I"</span><span class="syntaxkeyword">).</span><span class="syntaxdefault">unpack</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"i"</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> if import</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">i</span><span class="syntaxkeyword">]</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">==</span><span class="syntaxdefault"> </span><span class="syntaxstring">"I"<br /></span><span class="syntaxdefault">    end<br />    ret</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">@</span><span class="syntaxdefault">func</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">call</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">args</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">    return ret </span><span class="syntaxkeyword">||</span><span class="syntaxdefault"> 0<br />  end<br /><br />  alias Call call<br />end<br /></span>
                              

                              It looks as though the DL library supports callbacks. Maybe we should use it ??

                              I've also read that the DL library is 'on the outs', and they are planning to deprecate it and replace it with something else.

                              @jim said:

                              The win32-api ruby library does support callbacks, and we should really be using it anyway. it's more robust, and more stable (I've read.)

                              Yes.. I agree. Dan Berger is a "sharp cookie" when it comes to both Ruby and Windows coding. He is also on several of the MAJOR Ruby development teams including RubyGems and rdoc.
                              See his profile: RubyForge Profile for Daniel Berger

                              I'm not here much anymore.

                              1 Reply Last reply Reply Quote 0
                              • T Offline
                                thomthom
                                last edited by 29 Dec 2010, 03:07

                                @dan rathbun said:

                                @jim said:

                                I am not entirely sure the Win32API.so file we all have been using supports callbacks, which the windows enumerator functions require as arguments. ...
                                Specifically, calls to EnumWindows and EnumChildWindows can not be used with Win32API.

                                Actually Win32API.so is obsolete, and for some time, they have been suggesting coders migrate to using the DL library directly.

                                In Ruby vers 1.9.x and up... they no longer supply a Win32API.so file, instead they have replaced it with a Win32API.rb script that mimics the old so file, and translates Win32API calls into DL library calls.

                                Will that work for Ruby 1.8?

                                Thomas Thomassen — SketchUp Monkey & Coding addict
                                List of my plugins and link to the CookieWare fund

                                1 Reply Last reply Reply Quote 0
                                • D Offline
                                  Dan Rathbun
                                  last edited by 29 Dec 2010, 03:30

                                  @thomthom said:

                                  I think one can get lots of useful info if one can get the thread id of the SketchUp process. Any ideas of how one can do this.
                                  How about?
                                  Process.pid()
                                  Thread.main.object_id

                                  @thomthom said:

                                  I've been scanning the Win32 API a bit today looking for relevant functions.

                                  Well all the API functions for: [Processes and Threads](http://msdn.microsoft.com/en-us/library/ms684847(v)

                                  I'm not here much anymore.

                                  1 Reply Last reply Reply Quote 0
                                  • T Offline
                                    thomthom
                                    last edited by 29 Dec 2010, 11:46

                                    Ah - there we go, that might help.
                                    GetCurrentProcessId looks promising.

                                    Thomas Thomassen — SketchUp Monkey & Coding addict
                                    List of my plugins and link to the CookieWare fund

                                    1 Reply Last reply Reply Quote 0
                                    • T Offline
                                      thomthom
                                      last edited by 29 Dec 2010, 11:49

                                      pid = GetCurrentProcessId.call 4684 Process.pid() 4684
                                      It seem to return the same thing.

                                      Thomas Thomassen — SketchUp Monkey & Coding addict
                                      List of my plugins and link to the CookieWare fund

                                      1 Reply Last reply Reply Quote 0
                                      • D Offline
                                        Dan Rathbun
                                        last edited by 29 Dec 2010, 13:14

                                        @thomthom said:

                                        pid = GetCurrentProcessId.call 4684 Process.pid() 4684
                                        It seem to return the same thing.

                                        Yes and it's the same as you'll see in the Task Manager, or using tlist.exe from the command line (for that Sketchup instance.)

                                        I'm not here much anymore.

                                        1 Reply Last reply Reply Quote 0
                                        • D Offline
                                          Dan Rathbun
                                          last edited by 29 Dec 2010, 13:34

                                          @dan rathbun said:

                                          It looks as though the DL library supports callbacks. Maybe we should use it ??

                                          My bad.. 😳
                                          Callbacks were added in 1.9.x, both 1.8.6 and 1.8.7 DL libs don't have the callback.rb file.

                                          sorry Thom

                                          I'm not here much anymore.

                                          1 Reply Last reply Reply Quote 0
                                          • 1
                                          • 2
                                          • 1 / 2
                                          1 / 2
                                          • First post
                                            1/40
                                            Last post
                                          Buy SketchPlus
                                          Buy SUbD
                                          Buy WrapR
                                          Buy eBook
                                          Buy Modelur
                                          Buy Vertex Tools
                                          Buy SketchCuisine
                                          Buy FormFonts

                                          Advertisement