How to read a global selection using MacRuby? - cocoa

How can I read a global UI selection within MacRuby? For instance, of selected text in Preview.
Having no experience in Ruby and Cocoa, I've decided to take a plunge and to write a small dictionary app to aid myself with translation. All the pieces are ready, I just need to know how to read selected text on hotkey.

You can't, because there isn't one.
There is not one global selection. There is one text selection per text view (or other selectable-text-containing view). A window may have any number of such views, an application may have any number of such windows open, and the user may have any number of such applications running.
A further problem is that not all applications are Cocoa. Of those that are, most are accessible, but not all; custom views may trip you up (think of the Text tool in a graphics editor, for example). If the user selects text in a non-Cocoa application, chances are you won't be able to read it.
If you want to access the selected text in the focused view in the focused window in the focused application, the best way to do that is to make your application provide a Service, which the user can invoke from nearly any Cocoa application and some of the more enlightened Carbon apps. That's the best you can do.
Apple's own Dictionary gets special treatment in AppKit (including the availability of a floating Dictionary panel in Cocoa and Carbon apps), but otherwise works the same way: It provides a service that shows up in every Services menu (if the user hasn't turned it off).

Related

Options for getting/setting Windows window states for a browser window

Our agency has a Java web application that uses a third party Java applet as a TIFF viewer. In this application javascript spawns a separate window (and yes, it must be a separate window). We are currently using an in-house ActiveX control so that the HTML window can have the window state, window size and position, and screen device presisted and restored via localStorage. Our agency is IE11 only so for now using it is not a problem. It's embedded in the page and operates on the "containing window".
This control was made many years ago in VB6. It appears that Visual Studio doesn't support the creation of ActiveX controls, and I don't personally have the knowledge or skill to create one another way.
Please do not suggest the HTML DOM window and screen objects! Most answers I've searched for just refer to these! They can't get the entire browser window size (viewport + chrome + toolbars + titlebar), nor does javascript have any idea about Windows-specific things like window state and screen device (it's always the OS primary screen). I understand the HTML DOM can't be tied to anything OS-specific in order for it to be implementable on multiple platforms.
Up until now this control has worked pretty well - you can, for example, maximize on a given screen and restore the window to the same screen. But I realize that ActiveX won't be supported forever and it's IE only...It seems to me, though, that the need for such functionality can't be totally uncommon. I'm guessing that some may suggest that the application UI should be changed so that this is less of a problem - but being able to put the viewer on a different monitor from the application, and having that window be restored exactly to it's last position is important to us. I do understand that if you reuse that window the user only has to position it once, but we'd rather not require this of the user.
Question: are there any alternatives to interacting with the win32 API other than COM/ActiveX ? Are there any other methods of accurate window persistence that can know about screens other than the OS primary, and maximized/minimized/normal windows) that use something other than the Win32 API?

Program to drive a windows application

I would like to know is there a way to drive an existing windows application? I want to execute operations in an application like filling out text fields in a form, hitting next and submit buttons, etc. Basically what a user would do, I wanted to automate those operations. What would be the best way to achieve this?
Thanks
Mukul
It is possible (with limitations and quirks), if that particular Windows application uses native windows (so-called) controls (UI elements). Qt, for example, paints UI elements "by hand", while MFC applications uses Win API UI native (and expanded) elements. So, it depends.
You can explore application and it's UI elements using Spy++ tool inside Visual Studio (there are free alternatives available). Using these tools, you can look up target window class name, ID and other attributes that would help you to find and identify elements of interest using Windows API functions.
One can use EnumDesktopWindows, FindWindowEx, FindWindow, and others, to find window and it's inner control of your interest. Then, using SendMessage you can send various messages to set focus, emulate mouse clicks, set text for Edit control, simulate button clicks, etc, etc.
You can write such a program using UI Automation, which allows a program to discover and use the GUI of another application. It's how accessibility tools like screen readers interact with your applications.

Dialog as main Window?

Is it usual to use a Dialog as main Windows? So without registering any user class via RegisterClassEx? Can I do everything I do via CreateWindow()? Why should I create controls such as buttons,editboxes etc via CreateWindow() instead of just making a Dialog and use it as main Window?
I'd also like to know main difference between a dialog and a windows and why use one the first instead of the second.
Thanks
Is it usual to use a Dialog as main Windows?
Yes, it is quite common.
So without registering any user class via RegisterClassEx?
A dialog is usually a predefined window class, so there usually no need for registering.
I'd also like to know main difference between a dialog and a windows and why use one the first instead of the second.
Well, two big differences would be that you cannot resize a dialog box and it has no minimize or maximize buttons (by default, but there are workarounds for this). Keep in mind the name, dialog box. In other words they are used for having a dialog with the user (receive input and displays messages to user). In a sense they are just like any other window, underneath CreateWindowxx, etc. is called, etc. However, they are somewhat predefined windows which can be made quickly and there are limitations to what you can do with them.
Also, a dialog uses a dialog procedure rather than a window procedure, which does some default processing for you, such as initializing some controls, etc.
Yes, an application can be dialog-based. There's even a Wizard for that if your'e using VisualStudio and MFC.
In VS2010, Create New Project > MFC Application. In "Application Type" select Dialog Based. Click through the rest of the Wizard, and you're off to the races.
Dialog-based applications are much simpler, architectually, than other designs such as Document/View. As such, simple things are much easier to "bang out" quickly, but the limitations of the design become apparent when you try to do more complex things. You could end up replicating much of the Doc/View architecture in your dialog-based app in order to build a production-quality Dialog-based application. In that case, did you really save yourself anything?
A dialog is a kind of window just as all of the various controls like buttons are really just windows. You can think of a dialog as being a kind of window with a lot of extra functionality to support the kinds of things that dialogs are used for.
There are two types of dialogs, modal which display and expect you to use them and then dismiss them, and non-modal which display but which do not capture and keep the input focus until they are dismissed. You can see these two types used in applications where a modal dialog is used to display an error or require the user to make some setting and a non-modal acts as a kind of tool box that stays displayed and when you need it, you click on it to do something and other times you are using some other window in the application.
Normally a dialog would not have a menu bar but would instead have all of its controls visible or easily accessible via tabs or some other type of presentation. Visual Studio and other IDEs have dialog designers to allow the placement of various controls along with wizards to allow the controls to be tied to classes and class members.
Which brings up a major difference between a dialog and a window. A window is kind of an empty page and to do things with the page requires more work. A dialog has tools that make the design easy however you are also constrained in large part by the toolbox.
If you have an application that is focused on basically allowing a user to specify certain settings and then do some task, a dialog works fairly well. If you have something that requires more complicated user interaction, an application window as the base from which all of your other dialogs and controls will be managed and manipulated will be more necessary.

How to reparent a Cocoa window?

I need to host my window upon a window of another application.
How to enumerate windows of another Cocoa application? Is it possible to control
them?
If no: how can I draw upon a window of another application?
Thanks!
How to enumerate windows of another Cocoa application?
You can enumerate the windows of another application using the Accessibility API. It doesn't matter whether that application is Cocoa or not.
Is it possible to control them?
Here, it does matter, indirectly, whether the application is Cocoa (or Carbon using standard controls). More precisely, it matters whether the application is accessible.
It usually is possible to move another window, resize it, or do simple things with controls in it (such as press buttons).
It is not possible to tape one of your windows to a window in another application. You will have to observe its location and move your window when the other moves. Following a live drag this way is not possible.
If no: how can I draw upon a window of another application?
You can't. You can only draw in your own windows.
You can make a transparent overlay window and draw on that, but that gets you back to the problem of taping one of your windows to a window in another application.
You should probably ask a broader question about whatever it is you hope to achieve by taping one of your windows to a window in another application or by drawing into a window in another application.
Checkout CGWindow.h
CGWindowListCreateDescriptionFromArray() is probably what you're looking for.
Cocoa does not support reparenting of another application window, or drawing on it.
But, there're two ways to get windows attributes for all the applications, like position, size, z-order, etc.
Accessibility API (also allows to control a foreign application window: move, resize, press buttons on it, etc.). If a foreign application does not support Accessibility API, then...
Quartz Window Services and a sample code for them, called "Son of Grab".

Is there still a place for MDI? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Even though MDI is considered harmful, several applications (even MS Office, Adobe apps) still use it either in its pure form or some as a hybrid with a tabbed/IDE-like interface.
Is an MDI interface still appropriate for some applications?
I'm thinking of an application where one typically works with several documents at one time, and often wants to have multiple documents side to view or copy/paste between them.
An example would be Origin, where one has multiple worksheet and graph windows in a project; a tabbed or IDE-like interface would be much more inconvenient with a lot of switching back and forth.
On the mac, it's natural and convenient for an application to have multiple top-level windows to solve this, what is the preferred way in Windows if one doesn't use MDI?
The disadvantages of MDI are the following:
It generally requires the user to learn and understand a more complicate set of window relations.
Many simple actions can require a two-step process. For example, bringing a desired window to the foreground can require that the user first brings the container window forward then bring the right primary window in the container window forward. Resizing or maximizing a window can mean first adjusting the container window then the primary window within.
If multiple container windows are open, the user can forget which one has the desired primary window, requiring a tedious search.
Users are easily confused by the dual ways to maximize, iconify, layer, and close a window. For example they may close the entire app rather than a window within the container window. Or they may “lose” a window because they iconified it within the container window without realizing it.
The user is limited in the sizes and positions his or her windows can assume. Suppose I want to look simultaneously at 3 windows of one app and 1 from another app. With SDI, I can have each window take a quadrant of the screen, but I can’t do that with MDI. What if I want one window in the MDI to be large and the other small? I have to make the container window large to accommodate the large window (where it occludes the windows of other apps), but that wastes space when looking at the child.
Note that all of these disadvantages apply to tabbed document interfaces (TDI) too, with tabbed interfaces having the additional disadvantage that the user can’t look at two documents in the same container window side by side. Tabs also add clutter and consume real estate in your windows. However, overall TDI tend to be less problematic than MDI, so they might be preferred for special cases (read on)
In summary, it hard to think of any situation to use MDI. It’s no better than an SDI while adding more complexity and navigation overhead, and working poorly with the windows of other apps.
There’s no reason an app can’t have multiple top-level SDI windows. Even with an app like Origin, I don’t see a problem with a project being spread across multiple SDI windows as long as the project is well identified in each window. SDI also allows different kinds of windows (e.g., graph vs worksheet) to have different menus and toolbars, rather than hiding or disabling items depending on the active window (the former is confusing, and the latter wastes space).
SDI gives your users the more flexibility over either MDI or TDI. Users can overlap or maximize the windows, and use the taskbar/dock as a de facto tab interface. Users can alternatively resize and reposition the windows so they can look at multiple at once. Each window can be sized independently to optimize screen space. Whatever advantages an MDI or TDI may have, you may be able augment SDI to have those advantages too (e.g., provide a thumbnailed menu that makes switching among windows faster than using the taskbar and comparable to selecting tabs, or provide a control that iconifies all windows of an app with one click).
Unless you have compelling reasons to use a TDI, go SDI to allow this flexibility. Compelling reasons include some subset of the following:
Each tab is used for unrelated high-order tasks and user will not be switching among tabs frequently or comparing information across tabs.
You’re working with very low-end users who are ignorant of or confused by the taskbar/dock and multiple windows, and don’t know how to resize windows (it seems compelling tab imagery works better than the taskbar for such users).
You anticipate there’re typically be a large set of tabs (e.g., 4 or more) and you can control their display in a manner more effectively for the task than the OS can if they were SDI windows on the taskbar/dock (e.g., with regard to order and labeling).
With SDI, you’re having problems with users confusing the toolbars or palettes of inactive windows with active windows.
Tabs are fixed in number and permanently open (e.g., when each tab is a different component of the same data object). The user is not saddled with trying to distinguish between closing a tab and closing the entire window; figuring out the window to navigate to is not an issue because all windows have the same tabs.
There is really only one way to properly arrange the data for task, with no variation among users or what they actually use the app for. You might as well set it up for the user with a combination of tabs and master-detail panes and rather than relying on the user to arrange and size SDI windows right.
In summary, given your users’ abilities, app complexity, and task structure, if your app can manage the content display better than the user/OS, use TDI, otherwise use SDI.
Note that the examples you used (MS Office and Adobe applications) are big programs and have lots of features. Users will be dealing with that program, and only that program for much of the program's lifetime.
Newer versions of MS Office (2007) and Adobe Photoshop (CS4) use multiple windows and tabs, respectively.
Note that with Windows 7, MDI's will probably lose popularity even more because of the extra power of tabs given by Microsoft's API's (although you needn't strictly use tabs -- MDI windows could work, but would be more confusing for the user than usual).
The old-style MDI (where to switch between documents, you had to go through the Windows menu) was annoying. The newer MDI (like tabs in Opera and Mozilla) make switching between documents very easy and seem to have been accepted well. They also don't clutter your taskbar as happens if you had more than one document open in something without MDI.
The main advantage of MDI is when you want to keep track of two or more windows at the same time, and those windows need to be grouped together. For example, there's a running process in one window, but you need to work on another window, MDI would be the most ideal.
I agree with slavy13 (old-MDI = bad, new-MDI = much better). But don't use programs like Microsoft Excel as your model. Ick! You get one window on your desktop, regardless of how many spreadsheets you have open (which may or may not be your preference.) But you get one taskbar icon for each and every document you have open. And your Alt+Tab window similarly has one icon for each document you have open. Plus, there is an additional icon in there just for "Excel" which takes you to whichever document happens to be "current". So yeah, do your MDI like Mozilla. Or at least give your users the option of switching to the cleaner style.
To more succinctly answer your question, I feel the answer is yes, MDI is still appropriate in some instances. But, in all things, moderation is the key.
It appears that multiple top-level windows is the way to go. As for whether there should be one global app instance or one per document is up to you I think. It's not visible to the user.
Only one benefit for MDI:
Programs that use large amounts of resources, such as Adobe Photoshop, often have an MDI due to the prohibitive cost of running more than one instance at a time.
But you shouldn't develop programs that drain huge amounts of resources to start with.
One advantage I can see for MDI occurs if a lot of screen real estate is going to be used for stuff that's shared among many windows. It may be more logical to have such material at the top or side of the enclosing window than to have it repeated in each SDI window, or have it appear in a window entirely separate from the SDI windows. For example, a chat program might have a status pane and a control pane. Having those be somewhat tied visually tied to the chat windows might be better than having them as standalone windows.

Resources