by thomthom » Mon Dec 27, 2010 7:59 pm
Here's a snippet to get the handle for the SketchUp window the calling ruby script belongs to. - Code: Select all
GA_ROOTOWNER = 3
def self.get_sketchup_window hwnd = GetActiveWindow.call return nil if hwnd.nil? GetAncestor.call(hwnd, GA_ROOTOWNER) end
(EDIT: This method will fail if the SketchUp window isn't the active window.)Alternative safer method here: viewtopic.php?f=180&t=33756&start=15#p297228
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by Dan Rathbun » Mon Dec 27, 2010 8:12 pm
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. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by thomthom » Tue Dec 28, 2010 1:10 am
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...
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by thomthom » Tue Dec 28, 2010 1:01 pm
Further testing: the method will fail if the SketchUp window isn't the active window.
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by honoluludesktop » Tue Dec 28, 2010 10:34 pm
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?
-

honoluludesktop
- In Remembrance
-
- Posts: 2219
- Joined: Fri Sep 12, 2008 12:08 am
- Location: Hawaii
by Dan Rathbun » Wed Dec 29, 2010 12:24 am
honoluludesktop wrote: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. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by thomthom » Wed Dec 29, 2010 1:55 am
GetActiveWindow http://msdn.microsoft.com/en-us/library ... 85%29.aspxThe 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.
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by Jim » Wed Dec 29, 2010 2:11 am
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.)
Last edited by Jim on Wed Dec 29, 2010 2:26 am, edited 1 time in total.
Hi
-
Jim
- Global Moderator
-
- Posts: 4678
- Joined: Mon Nov 12, 2007 10:13 pm
- Location: ohio
- Name: Jim
- Operating system: Windows
- SketchUp version: 2017
- License type: Pro
- SketchUp use: hobby
- Level of SketchUp: Intermediate
-
by thomthom » Wed Dec 29, 2010 2:22 am
Jim wrote: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?
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by Jim » Wed Dec 29, 2010 2:26 am
thomthom wrote: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
-
Jim
- Global Moderator
-
- Posts: 4678
- Joined: Mon Nov 12, 2007 10:13 pm
- Location: ohio
- Name: Jim
- Operating system: Windows
- SketchUp version: 2017
- License type: Pro
- SketchUp use: hobby
- Level of SketchUp: Intermediate
-
by thomthom » Wed Dec 29, 2010 3:05 am
The example I saw of it: http://stackoverflow.com/questions/3327 ... 09#3328209Seemed to use namespace Win32 as oppose to Win32API. So this is not a module that ships with Ruby?
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by Dan Rathbun » Wed Dec 29, 2010 3:12 am
thomthom wrote: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. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by Dan Rathbun » Wed Dec 29, 2010 3:32 am
thomthom wrote: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. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by Dan Rathbun » Wed Dec 29, 2010 3:58 am
Jim wrote: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 - Code: Select all
warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: Win32API is deprecated after Ruby 1.9.1; use dl directly instead" if $VERBOSE
require 'dl'
class Win32API DLL = {} TYPEMAP = {"0" => DL::TYPE_VOID, "S" => DL::TYPE_VOIDP, "I" => DL::TYPE_LONG}
def initialize(dllname, func, import, export = "0", *rest) @proto = [import].join.tr("VPpNnLlIi", "0SSI").sub(/^(.)0*$/, '\1') handle = DLL[dllname] ||= DL.dlopen(dllname) @func = DL::CFunc.new(handle[func], TYPEMAP[export.tr("VPpNnLlIi", "0SSI")], func, *rest) end
def call(*args) import = @proto.split("") args.each_with_index do |x, i| args[i], = [x == 0 ? nil : x].pack("p").unpack("l!*") if import[i] == "S" args[i], = [x].pack("I").unpack("i") if import[i] == "I" end ret, = @func.call(args) return ret || 0 end
alias Call call end
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 wrote: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. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by thomthom » Wed Dec 29, 2010 4:07 am
Dan Rathbun wrote:Jim wrote: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?
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by Dan Rathbun » Wed Dec 29, 2010 4:30 am
thomthom wrote: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_idthomthom wrote:I've been scanning the Win32 API a bit today looking for relevant functions.
Well all the API functions for: Processes and Threads
I'm not here much anymore. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by thomthom » Wed Dec 29, 2010 12:46 pm
Ah - there we go, that might help. GetCurrentProcessId looks promising.
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by thomthom » Wed Dec 29, 2010 12:49 pm
pid = GetCurrentProcessId.call 4684 Process.pid() 4684 It seem to return the same thing.
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by Dan Rathbun » Wed Dec 29, 2010 2:14 pm
thomthom wrote: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. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by Dan Rathbun » Wed Dec 29, 2010 2:34 pm
Dan Rathbun wrote: 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. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by thomthom » Wed Dec 29, 2010 2:56 pm
GetCurrentThreadId I think this one is what we can use to get associated window handles. Just need to get callbacks working so we can use EnumThreadWindows to get the windows for the calling thread.
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by thomthom » Wed Dec 29, 2010 3:45 pm
Jim wrote:thomthom wrote: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
I just tried it, works fine with Win32API. Here's a bastardised proof of concept snippet where I found the SketchUp window regardless if it had focus or not. - Code: Select all
# http://stackoverflow.com/questions/3327666/win32s-findwindow-can-find-a-particular-window-with-the-exact-title-but-what EnumWindows = Win32::API.new('EnumWindows', 'KP', 'L', 'user32') EnumThreadWindows = Win32::API.new('EnumThreadWindows', 'LKP', 'I', 'user32') GetCurrentThreadId = Win32API.new("kernel32.dll", "GetCurrentThreadId", '', 'L')
# Detect the toolwindows even if Hide Dialogs is active. def enum_sketchup_windows threadId = GetCurrentThreadId.call enumWindowsProc = Win32::API::Callback.new('LP', 'I'){ |handle, param| #puts "EnumWindows - Callback" #puts "> handle: #{handle}" #puts "> param: #{param.inspect}" window_text = get_window_text(handle) window_text.strip! # Remove trailing NULL character p window_text unless window_text.empty? if !window_text.index(param).nil? puts "window was found: handle #{handle}" 0 # FALSE - stop looking after we find it 1 # TRUE else 1 # TRUE end } EnumThreadWindows.call(threadId, enumWindowsProc, 'SketchUp') end
# Takes the first enumerated window for the calling SketchUp thread and fetches # the root owner which should be the SketchUp window. (Not tested against wxSU) # # Is the enum required to get just one window? Any other function to get an # arbitrary window from the SketchUp thread? def find_sketchup_window threadId = GetCurrentThreadId.call hwnd = 0 enumWindowsProc = Win32::API::Callback.new('LP', 'I'){ |handle, param| hwnd = GetAncestor.call(handle, GA_ROOTOWNER) 0 } EnumThreadWindows.call(threadId, enumWindowsProc, 'SketchUp') hwnd end
Remaining issues: - Migrate Win32API to Win32::API for all function calls.
- While testing I eventually got an exception that said there was too many callbacks initiated. Seems there might be a limit. I have not looked into this further, but I think once might have to make one callback proc, and then delegate to the appropriate handling method based on param.
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by thomthom » Wed Dec 29, 2010 3:56 pm
= Documentation The source file contains inline RDoc documentation. If you installed this file as a gem, then you have the docs.
Where do you get the source code? I tried to install the gem, but got this error: gemInstallError.png
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by Jim » Wed Dec 29, 2010 4:18 pm
It is a c-language based extension, and apparently isn't available already compiled for your platform. So you would need to compile it. This is the advantage of using the mingw32 Ruby Installer with devkit - it automatically builds native libraries. http://rubyinstaller.org/downloads/
Hi
-
Jim
- Global Moderator
-
- Posts: 4678
- Joined: Mon Nov 12, 2007 10:13 pm
- Location: ohio
- Name: Jim
- Operating system: Windows
- SketchUp version: 2017
- License type: Pro
- SketchUp use: hobby
- Level of SketchUp: Intermediate
-
by thomthom » Wed Dec 29, 2010 4:33 pm
But where is the source code - since it's suppose to contain the documentation?
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by Jim » Wed Dec 29, 2010 4:36 pm
For me, it is here:
C:\Ruby186\lib\ruby\gems\1.8\gems\win32-api-1.4.7-x86-mingw32\ext\win32
Hi
-
Jim
- Global Moderator
-
- Posts: 4678
- Joined: Mon Nov 12, 2007 10:13 pm
- Location: ohio
- Name: Jim
- Operating system: Windows
- SketchUp version: 2017
- License type: Pro
- SketchUp use: hobby
- Level of SketchUp: Intermediate
-
by thomthom » Wed Dec 29, 2010 5:05 pm
hm... guess I have to look into that ming-thing...
Anyway - I have produced a code which appear to return the handle for the SketchUp window of the calling thread. I created a EnumWindowsProc to delegate enumeration messages in order to avoid Error: #<Win32::API::Error: too many callbacks are defined.>. I really want to know what this limit is. This is the first draft, I expect there is a better way to deal with this.
But, we do get a reliable window for the SketchUp window we want - as far as I have been able to test.
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by thomthom » Wed Dec 29, 2010 5:08 pm
Maybe we can handle drag and drop by callbacks. Or intercept window messages so we can simulate the roll-up/down of toolwindows.
Still, OSX users are out of luck here...
-

thomthom
- PluginStore Author

-
- Posts: 19457
- Joined: Tue Nov 13, 2007 12:47 pm
- Location: Trondheim, Norway
- Name: Thomas Thomassen
- Operating system: Windows
- SketchUp version: 2019
- License type: Pro
- SketchUp use: other
- Level of SketchUp: Advanced
-
by Dan Rathbun » Thu Dec 30, 2010 3:41 am
Here's some interesting info: - Code: Select all
# # some Sketchup window properties: # # AutomationId = "" # # CLASS = "Afx:00400000:b:00010011:00000006:00790557" # *** the last octet changes each time Sketchup is run, # examples: "Afx:00400000:b:00010011:00000006:0012077F" # "Afx:00400000:b:00010011:00000006:000E0699" # # ControlType = "ControlType.Window" # LocalizedControlType = "window" #
The main application window is the only one with a classname like this, and also the only one with a LocalizedControlType that equals "window". ALL dialogs including WebDialogs, are: - Code: Select all
# # ClassName = "#32770" # ControlType = "ControlType.Window" # LocalizedControlType = "Dialog" #
I'm not here much anymore. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by Dan Rathbun » Thu Dec 30, 2010 4:14 am
thomthom wrote:I have produced a code which appear to return the handle for the SketchUp window of the calling thread.
Are you planning on distibuting a pre-compiled win-api as part of TT_Lib2 ?? I have a few issues with this. (1) It's not in the correct folder. What if a person already has it (and possibly a newer version,) installed ? require will not recognize the path string you have in that example, and would load the older version down under your TT_Lib2 folder. That would overwrite the newer classes that might be loaded, if they were loaded first. OR.. since "T" comes before "W" your version would get loaded first, and when a normal version gets loaded after... your code might get broken. (I say "might" as newer versions are usually better.) So? I like the idea of someone precompiling Berger's WinUtils, and zipping them for manual install by the community (and/or creating a one-click-installer for dummies.) But they should be in the proper folder ... and likely a path to them appended to the $LOAD_PATH array. How much of Berger's suite would the distro have? the bare bones min or the whole thing?
I'm not here much anymore. But a PM will fire email notifications.
-

Dan Rathbun
- PluginStore Author

-
- Posts: 5051
- Joined: Tue Oct 06, 2009 3:06 am
- Location: Florida, USA
- Name: Dan Rathbun
- Operating system: Windows
- SketchUp version: 2015
- License type: Pro
- SketchUp use: education
- Level of SketchUp: Advanced
by Ad Machine » 5 minutes ago
-
Ad Machine
- Robot
-
- Posts: 2012
-
Return to Developers' Forum
|