I'm developing an "automatic message" add-in for Office Communicator 2007, but I need to know how to identify if another user opens the IM Window (not me, but another user).
I have the following event:
private void communicator_OnIMWindowCreated(object pIMWindow)
{
if ((chk_Enabled.Checked))
{
IMessengerConversationWndAdvanced imWindow = pIMWindow as IMessengerConversationWndAdvanced;
imWindow.SendText(TxtAutoMessage.Text);
}
}
Is there a way? Thanks!
unfortunately the Communicator Automation API doesn't support this directly. The only workaround I've found involves trapping the OnIMWindowContactAdded event.
For a conversation started by you, the following events fire in this order:
OnIMWindowCreated
OnIMWindowContactAdded (for yourself)
OnIMWindowContactAdded (for the other participant)
For a conversation started by another participant, the following events fire in this order:
OnIMWindowCreated
OnIMWindowContactAdded (for the other participant)
So when the participant initiates the conversation, you don't see yourself added as the contact.
You could use this as follows
On trapping OnIMWindowCreated, store the window handle (pIMWindow.HWND) in a dictionary (so you can handle multiple conversation windows)
On trapping OnIMWindowContactAdded, look for the handle in the dictionary. If this is the first Added event you've seen for the window, the rule is: if the contact is you (IsSelf), then you started the conversation. Otherwise, another contact started the conversation.
It's not the most satisfactory solution (they never are when you work with the Automation API ;o) ), but it should get you there.
Related
i have work on an app that manipulate some application context menue to extend its functions, i have checked all the common posts here on stackOverFlow on how to manipulate the menu context using Windows api in C# using functions like GetMenu(...), InsertMenuItem(...), ShowOwnedPopups(...) and that comes in vain, here is the scenario, the application i wanna manipulate it context menu has many context menus in many parts but i want to manipulate certain one which belongs to the viewer part. so i have used spy++ to figure the the handle of the viewer and a send a message WM_CONTEXTMENU using SendMessage(...) function. the menu finally appears and i have its handle.
i guess after i get the handle it would be constant for the life time of the program for the single running time, but i figured out that the handle is changing every single time a i have clicked right click. and the parent of the context menu isn't the viewer area itself but the desktop that's was disappointing.
so i have two problems
1- i can't get the handle directly as using GetMenu(...) passing the handle of the viewer returns null, after some search if found that the context menu has a class name of "#32768" so i have filtered all the open windows to get the one that its class name equlas "#32768". and now i can access the handle from my c# code not from the spy. but here is an comming issue: if there is a sub menue.. it also have the same class and unfortunately this is totally logical :/
2- i can't get the context handle before it is shown and if it is shown, i can't manipulate it as i know. The second thing is that the context handle continuously changes every single time i right click the mouse. so i can't pass the first time i click then save the handle for the next clicks to make it work.
any suggestion are very welcomed.
First of all you should figure out if you can just send it a WM_COMMAND message to perform your command. A context menu might not use that message but if the application also has a normal menu then it is likely that it will handle the message. Note that the command id might change between program versions.
All Win32 HMENU menus use the same class and MN_GETHMENU is the only related documented message.
The recommended solution is to use UI Automation/MSAA to navigate the UI of other applications.
I have created a windows service in c#. How can I call a function whenever a key is pressed, and in this function get the value of the key. I need it for both key up and key down.
My goal is to send an email if a certain series of keys were pressed. For example if you press h-e-l-l-o, no matter where you type it even on the desktop, the program should send the email.
Also, it's ok for me to implement it in another way. I need a program that runs in the background and do something when a key is pressed.
How can I do such thing?
An example would be helpful.
As somebody has already commented, a Windows service does not have a foreground window which can receive keyboard focus or Windows keyboard messages. So your only option to achieve exactly what you're after is to use a low level event hook to receive keyboard events.
Note, however, that these are system-wide events and your service might be flooded with them. They're useful in applications like screen readers and other assistive technology, but I'd recommend trying to think about whether there is some other way to do what you want to do before using this approach. For example, can you just run an application in the system tray and subscribe to WM_HOTKEY messages via calls to RegisterHotKey?
Here's an example of a low-level keyboard hook in C#.
The best solution I found:
Generally author creates .NET wrapper on a low-level methods from user32.dll assembly that make using those methods quite pleasant and enjoyable.
private LowLevelKeyboardListener _listener;
_listener = new LowLevelKeyboardListener();
_listener.OnKeyPressed += _listener_OnKeyPressed;
_listener.HookKeyboard();
void _listener_OnKeyPressed(object sender, KeyPressedArgs e)
{
this.textBox_DisplayKeyboardInput.Text += e.KeyPressed.ToString();
}
here the original link
We're trying to create an Outlook add-in that displays a custom suggestion (autocomplete) drop-down list as a person types in the To/CC field of a new Email window in Outlook. We have met a roadblock because we cannot find out how to listen to the keystroke events on these fields in Outlook. We tried using the MailItem.PropertyChange and MailItem.BeforeCheckNames but neither of them corresponds to a keystroke event or even a periodic callback.
Any help will be appreciated.
Here's a long shot - quite complicated but it sounds like you've already given up on the trivial solutions:
Maybe you can find the handles to the To/CC windows, and attach to their text changed?
If you run Spy++ you can see these fields are quite unique and easy to find. Then you need to run according to their re-paint or whatever.
Best of luck!
Nili
Msdn doc for IsolatedStorageFile.IncreaseQuotaTo states that:
To increase the quota, you must call
this method from a user-initiated
event, such as in an event handler for
a button-click event. When you call
the IncreaseQuotaTo method, the common
language runtime in Silverlight
presents a dialog box for the user to
approve the request. If the user
declines the request, this method
returns false and the quota remains
the same size.
How does Silverlight know that the method was called from a user-initiated event like a button click and not from some other thread?
More specifically: What is a user initiated event? Is there any way to overcome this limitation?
And another question:
I do some automatic downloads of files when user first accesses my application, but I don't want the user to press "Download" and then when I detect more space is needed call IncreaseQuota and have the "Silverlight dialog" appearing asking for more space.
I want to start the download automatically (not user initiated), and if I detect more space is needed, call IncreaseQuota and hence have the "Silverlight dialog" appear. (No user pressing download).
After much digging, I did find out what a user initiated event is. Seems that msdn doc specifies what a user initiated event in the section related to "events overview", but there's no link between documentation of IsolatedStorageFile.IncreaseQuotaTo and Events Overview
So a user initiated event according to the definition is:
Silverlight enforces that certain
operations are only permitted in the
context of a handler that handles a
user-initiated event. The following is
a list of such operations:
Setting IsFullScreen.
Showing certain dialogs. This includes
SaveFileDialog, OpenFileDialog, and
the print dialog displayed by
PrintDocument.Print.
Navigating from a HyperlinkButton.
Accessing the primary Clipboard API.
Silverlight user-initiated events
include the mouse events (such as
MouseLeftButtonDown), and the keyboard
events (such as KeyDown). Events of
controls that are based on such events
(such as Click) are also considered
user-initiated.
API calls that require user initiation
should be called as soon as possible
in an event handler. This is because
the Silverlight user initiation
concept also requires that the calls
occur within a certain time window
after the event occurrence. In
Silverlight 4, this time window is
approximately one second.
User-initiated event restrictions also
apply to usages of JavaScript API for
Silverlight.
When Silverlight is in full-screen
mode, some input events are
deliberately limited for security
reasons, although this can be
mitigated for out-of-browser
applications using elevated trust. For
more information, see Full-Screen
Support.
Although I don't see "IncreaseQuotaTo" inside the list of "operations", I'm guessing they just forgot it, since the behavior/limitations are the same as the ones described in the doc.
I was curios how exactly does silverlight know what a user initiated event is but after digging through .net framework source code I've got to a dead end:
if ((browserService == null) || !browserService.InPrivateMode())
{
//..
}
return false; //means that IncreaseQuota will fail
where browser.IsInPrivateMode is:
[SecuritySafeCritical]
public bool InPrivateMode()
{
bool privateMode = false;
return (NativeMethods.SUCCEEDED(UnsafeNativeMethods.DOM_InPrivateMode(this._browserServiceHandle, out privateMode)) && privateMode);
}
where DOM_InPrivateMode is in a DllImport["agcore"] which according to microsoft is confidential :(
So it looks like I won't find out soon how they're detecting user initiated events.
Thinking it more about it, I guess microsoft didn't want a user to have many tabs open in a browser and then poof: I call automatically IncreaseQuotaTo.
The IncreaseQuotaTo is a browser modal dialog. This means you can't navigate to other browser tabs while is active.
So if the user has now moved from my page to the tab with google.com, and if I would be able to call IncreaseQuotaTo with a delay, the user might think that google.com is asking for more storage :).
This would be a security breach indeed.
Had they implemented this with a page level dialog, then that would have been probably more easily hacked (or worked around).
So all in all, thinking of it, I'm starting to see why they implemented it like this and why these limitations exist.
The documentation isn't incomplete.
If I do this... button_click(..) { new UserControl() }... Does this still count as a user initiated event?
Yes. But what has that little bit of extra code really achieved?
What i've personally never experimented with is exactly what consitutes a user event; IOW is a mouse-over considered a user event? This will be very simple for you to try, and there are a multitude of other things you can experiment with. If necessary you could have a splash screen popup that welcomes the user and they have to click on it to dismiss it, at which point you make the request. It may seem a bit corny, but you can get away with things like this if you present it well.
Note that the prompt is a one-time thing. If you prompt the user and they accept, that storage is persisted for your application between visits, which means you don't need to prompt them again the next time they use your control, your quota is still increased from last time (unless the user has deliberately deleted it, which they can do by right clicking on the Silverlight control and then going to the Application Storage tab).
This may be a long short or not even possible but no harm in asking.
What I am trying to do is monitor an application for any new windows it creates in its MDI control. I have implemented hooking in C# and can capture the MDICREATE window message but because I need to get information about the window after is has been created the MDICREATE message isn't much help because at that stage the window hasn't been created in the other application yet.
Without going into to much detail I just need to be able to see when a new window has been created.
Is this possible?
Thanks
I'm not aware of another message that gets the info that you are looking for off hand. But if that message works for you, you could hook that message and then do another scan of the windows to find the one you are missing. You can enumerate the child windows of the parent window. Use Spy++ to see the exact window hierarchy.
If you can watch for a particular function call, I would use some kind of hooking library to grab that (EasyHook comes to mind).
You can hook the MDI create function (assuming there is one), watch for that, then inn your code, call the original and do any lookups using the returned value. You'll have access to the returned value and any parameters, so you should be able to get some info out of those.
Two options off the top of my head.
Hook the WM_MDIACTIVATE event, the first time the window is being activated, use a flag to determine the first time the window is being activated.
If you need to run your code after the WM_MDICREATE or WM_MDIACTIVATE, you can post a new custom message from one of these messages, which is then handled after these messages have completed. You then write your code to handle the custom message.