AkelPad Forum Index AkelPad
Support forum
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Trigger (auto execute) an application when opening file
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AkelPad Forum Index -> Discussion (English)
View previous topic :: View next topic  
Author Message
r0n



Joined: 14 Jun 2014
Posts: 18

PostPosted: Sat Jun 14, 2014 4:13 am    Post subject: Trigger (auto execute) an application when opening file Reply with quote

Is there a (simple) way to do the following:

Every time I open a textfile within Akelpad, execute a file (and pass the filepath as a parameter to the executable).

I am experimenting with Akelpad for a week now and I read the documentation on:
http://members.shaw.ca/atbcls/akelpad/

I am trying to write mini applications (application is actually a to big word) that should interact with akelpad and I am doing this in the macro application quick macros
The application allows programming in a language that can interact with the windows API and the language might be remotely comparable to VBS/C++. However I am not remotely accomplished in both languages.

I assume my request needs some sort of way to "catch" a SendMessage from Akelpad (I probably am not using the correct terms, but I hope someone understands of what I am trying to say.)

I am aware that this is difficult request to be solved "simply" but I thought I give it a try and ask here.
Back to top
View user's profile Send private message
DV



Joined: 16 Nov 2006
Posts: 856
Location: Kyiv, Ukraine

PostPosted: Sat Jun 14, 2014 9:04 am    Post subject: Re: Trigger (auto execute) an application when opening file Reply with quote

r0n,
This can be easily done via the Scripts plugin.
For example, create the following .js script under AkelFiles\Plugs\Scripts:
TheScript.js
Code:
var hSubClass;

if (hSubClass=AkelPad.WindowSubClass(1 /*WSC_MAINPROC*/, MainCallback, 0x435 /*AKDN_OPENDOCUMENT_START*/))
{
  //Message loop
  AkelPad.WindowGetMessage();

  AkelPad.WindowUnsubClass(1 /*WSC_MAINPROC*/);
}

function MainCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 0x435 /*AKDN_OPENDOCUMENT_START*/)
  {
    AkelPad.Exec("cmd.exe"); // your command
  }
}


Read more in the document "AkelFiles\Docs\Scripts-Eng.txt".
To see the available messages and notifications (such as AKDN_OPENDOCUMENT_START), download the sources of AkelPad or any of its plugin and refer to the file "AkelDLL.h".
Back to top
View user's profile Send private message
DV



Joined: 16 Nov 2006
Posts: 856
Location: Kyiv, Ukraine

PostPosted: Sat Jun 14, 2014 9:12 am    Post subject: Re: Trigger (auto execute) an application when opening file Reply with quote

Here is another version, probably closer to what you want to achieve:
TheScript.js
Code:
var hSubClass;

if (hSubClass=AkelPad.WindowSubClass(1 /*WSC_MAINPROC*/, MainCallback, 0x436 /*AKDN_OPENDOCUMENT_FINISH*/))
{
  //Message loop
  AkelPad.WindowGetMessage();

  AkelPad.WindowUnsubClass(1 /*WSC_MAINPROC*/);
}

function MainCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 0x436 /*AKDN_OPENDOCUMENT_FINISH*/)
  {
    var filePath = AkelPad.GetEditFile(0);
    AkelPad.Exec("notepad.exe \"" + filePath + "\"");
  }
}
Back to top
View user's profile Send private message
r0n



Joined: 14 Jun 2014
Posts: 18

PostPosted: Sat Jun 14, 2014 9:15 am    Post subject: Reply with quote

@DV

Thank you very much for this!!

It works perfectly!!!!!!!!

Thank you!

Спасибі! (I hope that is 'Thanks' in Ukrainian, or else my apologies!)
Back to top
View user's profile Send private message
r0n



Joined: 14 Jun 2014
Posts: 18

PostPosted: Sat Jun 14, 2014 5:24 pm    Post subject: Reply with quote

Sorry for new (final question).

As a final step I am trying the sendmessage method.

I can send a message using JSCRIPT to my created mini application using:
AkelPad.SendMessage(591236,32768+177,0,0)

591236 = the handle of application.

But I want the window handle to retrieved like this (or something like it):
Code:
var w = AkelPad.Open("", "form");

The target application window name = "form"
Of course this does not work, I get the error that the method/property is not supported.

The endgoal is to use the sendmessage code like this:

Code:

AkelPad.SendMessage(w,32768+177,0,0)


Is there a workaround? Is it possible?
The beauty of this solution is that I can have the mini-application loaded once and do a sendmessage to that window (target application).
In other words, in stead of constantly opening the same application when I open a document, I could do a sendmessage to the already opened application.

If there isn't a way to do this then the posted code by DV is something I can fallback to.

I searched in the AkelPad plugins manual, in the scripts section.
Back to top
View user's profile Send private message
DV



Joined: 16 Nov 2006
Posts: 856
Location: Kyiv, Ukraine

PostPosted: Sat Jun 14, 2014 6:44 pm    Post subject: Reply with quote

I'm not aware of an easy way to do it outside of your mini-application. It looks like Win API or several command-line tools need to be used in combination to achieve this. E.g. first you determine a process id (PID) of your mini-application, then enum its windows and retrieve the handle of the main window. (You can ask Google for something like "get process handle by path" and "get process main window".)
But it must be much easier to modify your mini-application in such way that it will search for another instances of itself on start, and delegate the command line parameters to already running instance, if any. (Actually, this approach also assumes some knowledge of Win API mentioned above, but at least all the modifications would reside in your mini-application, without need to invoke something external.)
Back to top
View user's profile Send private message
r0n



Joined: 14 Jun 2014
Posts: 18

PostPosted: Sat Jun 14, 2014 7:05 pm    Post subject: Reply with quote

@DV

Thank you very much for the feedback, you gave me some good ideas for approaching this!!!
I will post here when I have a workable solution!

Thank you again for your very fast response!!!
Back to top
View user's profile Send private message
r0n



Joined: 14 Jun 2014
Posts: 18

PostPosted: Sun Jun 15, 2014 12:40 am    Post subject: Reply with quote

I finally have a solution that almost perfectly works, It is quite simply actually on first runtime of my application I just let alter the script that does the sendmessage. I alter the line that contains the sendmessage and modify it to contain the correct handle (the application can output it).

The final thing I need is a way to send a send a string with the SendMessage command.

I have this
Code:

var x="test\r\n"
AkelPad.SendMessage(WinHandle,32768+177,x,0) // don't mind "WinHandle"


I do not know if this is the correct method to send a string with SendMessage and WM_APP (32768).

This is really the final thing I need and then my mini app could could work.



My mini app, only for the interested (it's not important or related to the problem described above):
I am trying to convert AkelPad into a notetaking application with the ability to have file attachments for each text note. AkelPad already has a tree based explorer plugin AND one click file open possibility AND tabbed display of text-files.
What my "add-on" does. It attaches a small stripped folder cabinet without the un-needed buttons. It displays the content "connected" to text-file.

The connection is made like this:
I have a subfolder called "attachments" within the "attachment" folder I have folders with the exact name of the textfile.
So if you open textfile "project_1.txt" the attached window opens the contents of "attachment\project_1"-folder. It automatically changes location when user navigates to other textfile. The attached window is small and moves attached with the AkelPad window and also hides itself when AkelPad is put into the background (and restores itself when AkelPad is restored).

Why I did this, other notetaking programs are bloated or put notes in a (proprietary) format. Als notetaking applications have very little automation options and command-line options. I discovered that AkelPad is small beast when it comes to command-line/scripting options...
And the notes and attachments are left in their original state (file/folder structure) AkelPad does the "heavy" lifting.
But I am not done yet I have it working 85% now, I do not know If can get it to work fully... I really hope so.

If can get this working I have some other projects I can connect this application! (but now I am really looking to far ahead).
Back to top
View user's profile Send private message
Instructor
Site Admin


Joined: 06 Jul 2006
Posts: 5523

PostPosted: Sun Jun 15, 2014 4:36 am    Post subject: Reply with quote

r0n
You cannot directly transfer data between processes.

Without creating file in temp folder, you have some alternatives: Interprocess Communications.

Added:
FileMappingExample.js
Code:
var hMainWnd=AkelPad.GetMainWnd();
var hMem;
var szName;
var szMem;
var dwMemSize=1000;

if (szName=AkelPad.MemAlloc(16))
{
  AkelPad.MemCopy(szName, "Global\\AkelPad", 0 /*DT_ANSI*/);

  //Create named memory object.
  if (hMem=AkelPad.SendMessage(hMainWnd, 1305 /*AKD_MEMCREATE*/, szName, dwMemSize))
  {
    if (szMem=AkelPad.SendMessage(hMainWnd, 1306 /*AKD_MEMMAP*/, hMem, dwMemSize))
    {
      AkelPad.MemCopy(szMem, "Test", 0 /*DT_ANSI*/);
      AkelPad.SendMessage(hMainWnd, 1307 /*AKD_MEMUNMAP*/, szMem, 0);
    }

    //Call external application. This application should call:
    //hMem=OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, "Global\\AkelPad");
    //szMem=MapViewOfFile(hMem, FILE_MAP_ALL_ACCESS, 0, 0, 1000);
    //Read szMem.
    //UnmapViewOfFile(szMem);

    AkelPad.SendMessage(hMainWnd, 1308 /*AKD_MEMCLOSE*/, hMem, 0);
  }
  AkelPad.MemFree(szName);
}
Back to top
View user's profile Send private message Send e-mail
FeyFre



Joined: 07 Aug 2007
Posts: 2060
Location: Vinnitsa, Ukraine

PostPosted: Sun Jun 15, 2014 8:56 am    Post subject: Reply with quote

r0n
Mapping memory ranges into space of other processes(call Marshaling) is only done by system for some messages <WM_USER (<1024), for all other messages user must take care of it manually.
WM_COPYDATA is only message which can send custom user data buffer to windows of other processes.
Back to top
View user's profile Send private message AIM Address Yahoo Messenger MSN Messenger
r0n



Joined: 14 Jun 2014
Posts: 18

PostPosted: Sun Jun 15, 2014 2:59 pm    Post subject: Reply with quote

@FeyFre and @Instructor

Thank you both for the feedback!
I will try with Instructors code and the WM_COPYDATA method.
Back to top
View user's profile Send private message
r0n



Joined: 14 Jun 2014
Posts: 18

PostPosted: Mon Jun 16, 2014 4:54 am    Post subject: Reply with quote

@Instructor

I am sorry to ask this, but could you give a WM_COPYDATA example?
(If possible).
The QM programming language I work in, supports it.

My apologies again: I got the filemapping working, the example had almost perfect example for me, but it contained the following:

Code:

OpenFileMappingA


This didn't work for me, so assumed this wouldn't work, I removed the "A" at the end and my environment (QM) recognized "OpenFileMapping"
Now I can send the string "test" successfully!!! (I do not know if "OpenFileMappingA" is official MSDN command, but by removing the 'A' I could work with it further).

I would still really appreciate an WM_COPYDATA example and how to read the string "test" if send it from my executable using FileMapping in AkelPad.
Back to top
View user's profile Send private message
Instructor
Site Admin


Joined: 06 Jul 2006
Posts: 5523

PostPosted: Mon Jun 16, 2014 4:30 pm    Post subject: Reply with quote

r0n
Why you need WM_COPYDATA, if you get file mapping working in QM?

FileMappingExample2.js
Code:
var hMainWnd=AkelPad.GetMainWnd();
var hMem;
var szName;
var szMem;
var dwMemSize=1000;
var pOutput="";

if (szName=AkelPad.MemAlloc(16))
{
  AkelPad.MemCopy(szName, "Global\\AkelPad", 0 /*DT_ANSI*/);

  //Create named memory object.
  if (hMem=AkelPad.SendMessage(hMainWnd, 1305 /*AKD_MEMCREATE*/, szName, dwMemSize))
  {
    //Write to shared memory.
    if (szMem=AkelPad.SendMessage(hMainWnd, 1306 /*AKD_MEMMAP*/, hMem, dwMemSize))
    {
      AkelPad.MemCopy(szMem, "Test", 0 /*DT_ANSI*/);
      AkelPad.SendMessage(hMainWnd, 1307 /*AKD_MEMUNMAP*/, szMem, 0);
    }

    //Call external application. This application should call:
    //hMem=OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, "Global\\AkelPad");
    //szMem=MapViewOfFile(hMem, FILE_MAP_ALL_ACCESS, 0, 0, 1000);
    //Read szMem.
    //Write szMem.
    //UnmapViewOfFile(szMem);

    //Read from shared memory.
    if (szMem=AkelPad.SendMessage(hMainWnd, 1306 /*AKD_MEMMAP*/, hMem, dwMemSize))
    {
      pOutput=AkelPad.MemRead(szMem, 0 /*DT_ANSI*/);
      AkelPad.SendMessage(hMainWnd, 1307 /*AKD_MEMUNMAP*/, szMem, 0);
    }

    AkelPad.SendMessage(hMainWnd, 1308 /*AKD_MEMCLOSE*/, hMem, 0);
  }
  AkelPad.MemFree(szName);
}
Back to top
View user's profile Send private message Send e-mail
r0n



Joined: 14 Jun 2014
Posts: 18

PostPosted: Mon Jun 16, 2014 5:11 pm    Post subject: Reply with quote

@Instructor

I tried most exe to exe communications with COPYDATA with QM.
I just wanted toe learn what the syntaxt is in .JS
But I am really happy 'filemapping' works!!!

Thank you for the FileMappingExample2.js example!!!

It is really appreciated!
Back to top
View user's profile Send private message
r0n



Joined: 14 Jun 2014
Posts: 18

PostPosted: Wed Jun 18, 2014 2:38 pm    Post subject: Reply with quote

Sorry for this question, but what is the code for triggering after a tab-switch? (Below is the code for triggering on a new document).
I need the exact same but only for a TAB switch. (when user clicks on an other tab.

I got my application working but I forgot about the possibility when the user focuses on another tab.

Code:

var hSubClass;

if (hSubClass=AkelPad.WindowSubClass(1 /*WSC_MAINPROC*/, MainCallback, 0x436 /*AKDN_OPENDOCUMENT_FINISH*/))
{
  //Message loop
  AkelPad.WindowGetMessage();

  AkelPad.WindowUnsubClass(1 /*WSC_MAINPROC*/);
}

function MainCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 0x436 /*AKDN_OPENDOCUMENT_FINISH*/)
  {
    var filePath = AkelPad.GetEditFile(0);
    AkelPad.Exec("notepad.exe \"" + filePath + "\"");
  }
}



I think these lines need to be adjusested?
if (hSubClass=AkelPad.WindowSubClass(1 /*WSC_MAINPROC*/, MainCallback, 0x436 /*AKDN_OPENDOCUMENT_FINISH*/))

or the following part:

uMsg == 0x436
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AkelPad Forum Index -> Discussion (English) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


SourceForge.net Logo Powered by phpBB © 2001, 2005 phpBB Group