Passing message to another window - delphi

I would like to write an application which passes every message it receives to another window. For example, I have an application where user can press some keys, move mouse over it, etc. and I want all these messages passed to, for example, MS Paint.
How do I do this? Any ideas? As far as I know, there may be a problem with sending key strokes to another window, so please advice as well.
EDIT
Okay, maybe I will give you more description of what I'm looking for.
My applications displays a window of another application on the form. Now I would like to control the other window using messages sent to my application's form (like key downs, mouse moves, etc.).
I have been thinking of passing all the messages my form receives to the window of the application I'm kind of 'embedding' into my own. By 'embedding' I mean making the application window display on my form.
Maybe there's another solution to my problem. Please advice.
Thank you for your time.

Some messages (i.e. input messages) arrive through the message queue and the rest are delivered straight to the recipient windows. What you are asking to do therefore requires you to do all of the following:
Implement a top level message loop that retrieves messages from the queue and sends them to the other app.
Reimplement all modal window loops to pass all messages on.
Replace the window procedure for all windows in your process with one that passes all messages on to the other app.
Look for other opportunities for messages to arrive that I have not covered.
I can't imagine that this is really going to be the solution to your problem, whatever that problem is.

Forwarding the messages is definitely possible and easy, but it likely won't do what you are expecting. Take a look here.

Override the form's DefaultHandler() and post every message it gets to the other form. If there are any explicit message handlers in the form or even some controls then you may not see those messages in DefaultHandler().

Related

How do I intercept form creation outside of the form in Delphi?

I'm trying to find a generic way to know when any form has been created with windows events or something of the sort. Currently I'm listening for WM_PAINT events within TApplicationEvents.OnMessage and then when I detect a Msg.hwnd I use FindControl() and see if the control is TForm. Then I know this form is being opened and I can then do some styling that is uniform across the hundreds of forms in the application.
When I listen for WM_CREATE events instead I get nothing. I'm not sure why. I was thinking this would tell me the form has been created, but evidently it doesn't. At the moment, there are a couple of timing issues that cause only a few forms to render, and then a split second later my styling kicks in. I only find this in some cases, and the majority of the cases it works just fine. So you have the form opening up on its original styling only to have it change a split second later - in a few cases.
The moment I detect a form like this, I also reassign its OnClose event so that I can perform some operation when the form closes, and then I redirect it to its original OnClose event handler. I've tried doing the same thing with its OnCreate and OnShow events, but that doesn't fire at all this way. The OnClose have been working perfectly, though.
I need my styling to kick in first before the form is shown. Any ideas?
I'm trying to find a generic way to know when any form has been created with windows events or something of the sort.
At the Win32 level, there are events related to window creation, such as:
SetWindowsHookEx() hooks, such as the HCBT_CREATEWND notification of a WH_CBT hook.
SetWinEventHook() events, such as EVENT_OBJECT_CREATE.
The problem with this approach is that the events are triggered after the underlying HWND struct has been allocated, but before it has been sent WM_(NC)CREATE messages. So, for instance, calling FindControl() inside a handler for these events won't work, because the VCL has not yet established the link between the HWND and the TForm object.
At the VCL level, there are no global events for Form creation. There is only the TForm.OnCreate event. If you need to handle that globally for all of your Forms (or even just some of them), you should create a base TForm class that overrides the virtual DoCreate() method (and/or other virtual methods, like CreateWnd(), PaintHandler(), WndProc(), etc), and then derive your desired TForm classes from this base class.
When I listen for WM_CREATE events instead I get nothing. I'm not sure why.
WM_CREATE is not a posted message. The Win32 CreateWindow/Ex() API sends this message directly to the window's message procedure while creating the window. The message does not go through the creating thread's message queue, and thus will never appear in the TApplication(Events).OnMessage event.
At the moment, there are a couple of timing issues that cause only a few forms to render, and then a split second later my styling kicks in. I only find this in some cases, and the majority of the cases it works just fine. So you have the form opening up on its original styling only to have it change a split second later - in a few cases.
If you are doing custom styling inside of a WM_PAINT handler, there should be no timing issues.
On the other hand, why are you not utilizing the VCL's built-in styling system? For instance, you can use TCustomStyleEngine.RegisterStyleHook() to register your own styling hook derived from TStyleHook for your desired classes.
Or, you could simply define your own custom Style for the VCL to use natively, no need to write any code for this.
The moment I detect a form like this, I also reassign its OnClose event so that I can perform some operation when the form closes, and then I redirect it to its original OnClose event handler. I've tried doing the same thing with its OnCreate and OnShow events, but that doesn't fire at all this way.
Correct, because the TForm object has already been created and its window is visible onscreen before it receives WM_PAINT messages from the OS.

Changing messages on Slack

So I'm attempting to change a message in slack through my slackbot at the end of a chain of events. I'm able to change it for the first few instances, but I'm not able to do the very last one. I'm 99% sure that it is because I have reached the 5 interactions limit since I am indeed going through 5 interactions with the user prior to my final message. If this is the case, is there a way to change a message without server responses? I ask because the last message is simply a thank you message to the user for participating. It doesn't actually require any input from data on the server to accomplish. I feel like I read about doing it somewhere, but for the life of me I cannot find it again. Any help or links would be greatly appreciated!
EDIT: The user is interacting with buttons through interactive messages to respond to some questions. The current method of updating messages are with chat.update and setting "response_type": "ephemeral" within the json params that I am sending.
An alternative method to using chat.update is to simply reply with the message to the request from Slack. This will replace the existing message by default. It has no limit that I am aware of, so it solves your problem.
This works great with slash commands and interactive messages.
See here for more details.

updating/dismissing message after dialog submitted

Is there a way to do any of the following:
a. Update a chat message that initiated a dialog.
b. Store "hidden" fields in a dialog.
Basically, I have a bot message that opens from a button on a message attachment. I know when the user clicks the button, I get the ts of the message and at that time I could alter it. However, the workflow is not complete until the user has submitted the dialog, but the submit on the dialog loses all the original_message stuff and the ts of the dialog being submitted no longer corresponds with the original, calling message.
If there was a mechanism to store hiddens, I could stash the original ts or the response url on the form itself.
Thanks! This is my first slack workflow, so any advise is appreciated as usual!
.....
The suggested duplicate answer refers to an interactive message, which I'm using to call the dialog already.
However, that isn't where my problem is, it is the dialog submission.
You don't have any access to the button elements on a dialog and the dialog element can only have 5 elements of type: text, select, text area. Plus it's a bit overkill considering that a action invocation from an interactive message actually includes the original message in the post back to your server.
So slack dev support got back to me:
Thanks for writing in, this is a great question!
You can use the callback_id parameter when calling dialog.open to store a string that will help your app locate the message. This callback_id will be returned to you in the dialog submission.
In your case, you could store the original message's ts and channel_id so that > you can locate the message to update.
I hope this helps! Let me know if you have any further questions!
So, it's a bit hacky (imo), but i did get it to work so I thought I'd close this question in case anyone else ran into this.
I'm just parsing the original ts value inside the callback w/ some other data i can use when the form submits. The only limitation to this is that it only stores 200 characters but that should be sufficient considering that is in addition to the 5 fields you have on the dialog and the other stuff slack gives you in the post (user, channel, etc).

Revulytics data not showing in Dashboard

I am using Revulytics SDK to track feature usage and came across the below problem.
I am sending feature usage after properly setting up the SDK configuration etc, using the EventTrack() method like this:
GenericReturn grTest = telemetryObj.EventTrack("FeatureUsage", textBoxName.Text.ToString(), null, false);
This returns OK and usually, I can see the usage data in the dashboard. However, after multiple tests, the data I am sending does not show up on the dashboard.
Can anyone hint me how to debug this? Thanks for any help!
I hit a similar issue when first working with this SDK.
I was able to address this as soon as I understood the following:
There are event quotas for the incoming events;
Event names are used for making the distinction.
So when I was sending dummy test data, it made it there, but when I sent some demo data for stakeholders, it was not showing up.
I think the same happens here. You're getting the event name form textbox.text... Pretty sure that varies every time you run the code.
Here are the things to keep in mind when testing your code:
the server has a mechanism to discard / consider events;
implicitly, it allows first xx events depending on the quota;
if you are sending more than xx events, they will not show up in reports.
So, you must control which events to discard and which to consider (there are a couple of levels you can configure, and based of them you can get the events in various types of reports).
Find the "Tracked Events Whitelist Management". You will be able to control these things form there.
This blog helped me (it is not SDK documentation): https://www.revulytics.com/blog/getting-started-with-usage-intelligence-part2-event-tracking
Good luck!

Lync SDK get sent or received text

Before anything I already saw this post:
Lync ConversationRemoved get current conversation text
I implemented that solution, but I really need to get the already sent or received text. The thing is, although I have my application registered as automatically open, if I get messaged with my window closed, I loose the first text (that's just an example). Anybody know how can I get the text?
I can't find it anywhere. Not in Conversation class or ConversationManager.
English is not my native language, hope you can understand me anyways.
You're missing the first text, I'm assuming you mean that the first line is missing? The text that starts the IM conversation can be found in the so-called "Toast".
The toast is the popup you get on your Lync client when a new conversation is started. In case of IM conversations, the first message is part of the toast and shown to the user in this popup. It is not send over the instant messaging flow.
MSDN documentation: ToastMessage class
The ToastMessage is a property of InviteReceivedEventArgs [MSDN]. Your incoming call handler will probably handle CallReceivedEventArgs, which inherits InviteReceivedEventArgs.
private void OnIncomingInstantMessagingCallReceived(
object sender,
CallReceivedEventArgs<InstantMessagingCall> e)
{
var toast = e.ToastMessage; // There she is. Mind you it can be null too.
}
If I understand the question correctly, you want to get the conversation that happened before your application connected? Like, getting a history? I don't think this is possible in the API - you can't use the API to look at historical data, only what is happening "now". You might have some success looking in the Lync database (though I don't know where!)

Resources