Basic Questions - LaTeX - Printable Version
-Shoutbox (https://shoutbox.menthix.net)
+-- Forum: MsgHelp Archive (/forumdisplay.php?fid=58)
+--- Forum: Messenger Plus! for Live Messenger (/forumdisplay.php?fid=4)
+---- Forum: Scripting (/forumdisplay.php?fid=39)
+----- Thread: Basic Questions - LaTeX (/showthread.php?tid=91088)
Basic Questions - LaTeX by Flippy on 06-17-2009 at 09:14 AM
Hi,
I have been trying to write a LaTeX add-in using C#.NET for Windows Live Messenger, and I came pretty close actually. I tried it in a normal windows application first, and it worked fine. Whenever a message received contains one or more "$$" tokens, the whole message is seen as a tex string, and the double signs "$$" are replaced by a single "$". The string is stored in a .tex file (including the \begin{document} etc preamble) and then converted to a .dvi file using the command line. Finally a PNG image is created from the dvi file, again using the command line. The PNG image is shown in a separate window (I am pretty sure it's not possible to show it inline in the actual MSN window, so I'm not even going to bother trying that).
When I tried it in my MSN Add-in however, it failed, because it seems I cannot create folders, files, or anything, from within the MSN Add-in. I keep getting security exceptions on the most silly things...
So I had a look at Plus! scripting, which may work for me.
I have the following questions. If the answers to these are all yes then I am pretty confident I can get it to work.
1. Can I use basic file I/O, like creating a folder in the Common Application Data directory for example? Can I also create files on the fly without getting security exceptions?
2. Can I use the command line (cmd.exe) and determine what commands to send? If not, can I execute a batch file?
3. Can I display a PNG image (somewhere on the hard disk), either in the current MSN window (probably not), or in a separate window??
Thanks for any help!
EDIT
I thought of another question, not of grave importance, but still useful:
4. If I receive a message with emoticons, does the Message string in the script (in the ReceiveMessage event I guess) display the shortcut of the emoticon, or does it simply skip it? In other words, does the emoticon come out as :) or will it be gone from the string?
5. Can I turn emoticons off temporarily when the user is typing a message the contains the "$$" string? Otherwise, you may get emoticons in your latex string...
RE: Basic Questions - LaTeX by ryxdp on 06-17-2009 at 09:26 AM
The short answers to all three of these questions are indeed "yes", as the language used in Plus!'s scripting engine is JScript, a rather flexible and easy to learn language.
quote: Originally posted by Flippy
1. Can I use basic file I/O, like creating a folder in the Common Application Data directory for example? Can I also create files on the fly without getting security exceptions?
Yes, you can, by creating an ActiveXObject:
jscript code: var x=new ActiveXObject('Scripting.FileSystemObject');
You will have to look up the functions you want on MSDN, though.
quote: 2. Can I use the command line (cmd.exe) and determine what commands to send? If not, can I execute a batch file?
Again, this can be solved using an ActiveXObject:
jscript code: var y=new ActiveXObject('WScript.Shell');
y.Run('cmd.exe');
quote: 3. Can I display a PNG image (somewhere on the hard disk), either in the current MSN window (probably not), or in a separate window??
This one is a little harder to do, but thanks to Messenger Plus!, we can make our own windows using the Plus! interface, using XML. If you read the Scripting documentation, it has a small introduction to creating your own windows that can be combined with the extra functions in the scripting engine to create a fully functional interface for your scripts.
quote: 4. If I receive a message with emoticons, does the Message string in the script (in the ReceiveMessage event I guess) display the shortcut of the emoticon, or does it simply skip it? In other words, does the emoticon come out as or will it be gone from the string?
The returned message will show the emoticon's shortcut.
quote: 5. Can I turn emoticons off temporarily when the user is typing a message the contains the "$$" string? Otherwise, you may get emoticons in your latex string...
As all emotions will be returned as their shortcuts, including custom emotions, it would be impossible to remove their strings from the message. If you mean preventing the actual emoticons displaying while the LaTeX string is being written, there may be some sort of registry edit, for example, that you can change temporarily, but I don't think its effect would be immediate.
Hope this helped
RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 09:48 AM
Thanks, that gives me hope.
For 1, 2 and 3 I will see what I can do. I'm not completely comfortable with the FSO object but I may get it to work anyway. Thanks.
For 4, and 5, that's ok. If the returned message shows the emoticon as string I suppose there isn't really a problem. The only 'problem' would be for the user typing the latex, as he would see emoticons when he's typing latex. But since the emoticons don't effect the message string, anything like (x) (little girl ) will still be seen as (x), and not as , so the latex will work correctly.
Thanks!
RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 10:01 AM
Erm, one thing lol, perhaps this deserves a new thread but I'll ask here first.
How do I replace all instances of a string with another string?
I want to replace every "$$" with a single "$" in the Message, so I tried this:
jscript code: var texCode = Message.replace("$$", "$");
The result is that only the first "$$" is replaced... The next occurences are not touched.
RE: Basic Questions - LaTeX by NanaFreak on 06-17-2009 at 10:11 AM
quote: Originally posted by ryxdp
As all emotions will be returned as their shortcuts, including custom emotions, it would be impossible to remove their strings from the message. If you mean preventing the actual emoticons displaying while the LaTeX string is being written, there may be some sort of registry edit, for example, that you can change temporarily, but I don't think its effect would be immediate.
if you want to remove them from the whole message you can just use /noicon at the start of the message... it removes all icons
just looking up the stuff about getting all instances with a regex...
RE: RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 10:14 AM
quote: Originally posted by NanaFreak
quote: Originally posted by ryxdp
As all emotions will be returned as their shortcuts, including custom emotions, it would be impossible to remove their strings from the message. If you mean preventing the actual emoticons displaying while the LaTeX string is being written, there may be some sort of registry edit, for example, that you can change temporarily, but I don't think its effect would be immediate.
if you want to remove them from the whole message you can just use /noicon at the start of the message... it removes all icons
No I mean that you can't type icons at all, so typing :) will not result in . Basically, I want to check what the user is typing (so he has not sent it yet! He is still typing), and if his message so far contains any "$$", then I want to disable the Show Emoticons option, so that he can type latex without emoticons interfering.
I realize this is probably not possible, but it doesn't hurt to ask
RE: Basic Questions - LaTeX by NanaFreak on 06-17-2009 at 10:17 AM
the best bet is to just do it as the message is sent...
also with your regex you want:
javascript code: var texCode = Message.replace(/\$\$/g, "$");
RE: RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 10:25 AM
quote: Originally posted by NanaFreak
the best bet is to just do it as the message is sent...
also with your regex you want:
javascript code: var texCode = Message.replace(/\$\$/g, "$");
Ahh, I was already trying regex but I forgot about the \$ instead of just $
Thanks!
And (according to ryxdp) any emoticons in the message will be replaced by their shortcut, so even if the user is typing emoticons such as f, the latex will still read f(x) correctly. It's only a little annoying to the user writing the latex, but he can just turn his emoticons off manually I guess...
RE: Basic Questions - LaTeX by NanaFreak on 06-17-2009 at 10:30 AM
quote: Originally posted by Flippy
And (according to ryxdp) any emoticons in the message will be replaced by their shortcut, so even if the user is typing emoticons such as f, the latex will still read f correctly. It's only a little annoying to the user writing the latex, but he can just turn his emoticons off manually I guess...
it will actually turn out as f(X) as messenger likes to make emoticons capitals... just to let you know
RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 10:37 AM
Oh darn, that will be a problem... Oh well, let's tackle it one at a time lol.
I have decided not to use the command line directly, but rather just execute a batch file. My code right now is this:
jscript code: function OnEvent_ChatWndReceiveMessage(ChatWnd, Origin, Message, MsgKind)
{
if (Message.indexOf("$$") != -1)
{
var fso = new ActiveXObject('Scripting.FileSystemObject');
// -----------------
// Create .tex file
// -----------------
var texFile = fso.CreateTextFile(path + "\\file.tex", true);
texFile.WriteLine("\\documentclass{article}\n\\pagestyle{empty}\n\\begin{document}\n");
// Replace all $$ with $
var texCode = Message.replace(/\$\$/g, "$");
texFile.WriteLine(texCode);
texFile.WriteLine("\n\\end{document}");
texFile.Close();
// -----------------
// Create DVI file and PNG file
// -----------------
var batFile = fso.CreateTextFile(path + "\\batFile.bat", true);
batFile.WriteLine("cd " + path);
batFile.WriteLine("latex file.tex");
batFile.WriteLine("dvipng -T tight -x 1200 -z 9 file.dvi");
batFile.Close();
var shell = new ActiveXObject('WScript.Shell');
shell.Run(path + "\\batFile.bat");
}
}
(path is the ScriptFilesPath)
It creates the .tex (latex) file with the correct equation and text, and then creates the batch file with three commands that will convert the tex file into a dvi, and then into a png image file.
(Of course, you need something like MikTex installed for this to work!)
However, the batch file is not running. I just guessed that I could run it with the Run command but apparently not... How do I run it?
RE: Basic Questions - LaTeX by NanaFreak on 06-17-2009 at 10:51 AM
i think the following command:
dvipng -T tight -x 1200 -z 9 file.dvi
it requires an input from the user... i think you just need to write a new line in the batfile of "q", this is a silent command as you dont need any text back from it...
hope this works...
RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 10:59 AM
What do you mean? The command doesn't need any input, I just need to run that command as it is. The file.dvi file is created just before that (with the latex command), and the dvipng commands creates a PNG image from the dvi file.
Anyway, I found the following code on another forum and this seems to work. I don't really know what I'm doing here though lol:
jscript code: // -----------------
// Create DVI file and PNG file
// -----------------
var batFile = fso.CreateTextFile(path + "\\batFile.bat", true);
batFile.WriteLine("cd " + path);
batFile.WriteLine("latex file.tex");
batFile.WriteLine("dvipng -T tight -x 1200 -z 9 file.dvi");
batFile.Close();
var shell = new ActiveXObject('WScript.Shell');
var oExec = shell.Exec(path + "\\batFile.bat");
while (oExec.Status == 0)
{
WScript.Sleep(100);
}
oExec = null;
shell = null;
Anyway.. it creates the PNG image
All that's left now is displaying it in a window!
Unfortunately, I haven't got a clue how to start lol... Do I need a separate XML editor? I have Visual Studio, maybe I can use that?
I suppose there is no visual editor? Eg, I cannot see the window before compiling the XML code?
Actually all I need is one window, roughly the size of the PNG image created, displaying the PNG image. Perhaps a button to close it, but that's not even a requirement. What controls am I looking at? In C# or VB I would use a picturebox, but there doesn't seem to be one..?
RE: Basic Questions - LaTeX by Matti on 06-17-2009 at 12:07 PM
First of all: welcome to our forums!
quote: Originally posted by Flippy
Unfortunately, I haven't got a clue how to start lol... Do I need a separate XML editor? I have Visual Studio, maybe I can use that?
There are some examples in the scripting documentation, but you'll learn the most by looking at other scripts. There are a lot of scripts which display an image in a window, have a look on how the image container is defined in the XML and how an image is assigned to the element.
You don't need a special editor, any text editor will do. It doesn't matter whether you prefer Notepad++ or Visual Studio, as long as you write valid XML and save your files as UTF-16 with BOM, Plus! will happily read your interfaces. If you still run into trouble with your interfaces, the Interface Tester can help you finding errors in your interface files.
quote: Originally posted by Flippy
I suppose there is no visual editor? Eg, I cannot see the window before compiling the XML code?
No, unfortunately there isn't. Many developers on the forums here have attempted to start up such a project, but it appears none of them succeeded in finishing it. At the moment, all script developers have to write the XML themselves. It sounds difficult at first, but you'll get the hang of it very quickly.
(By the way: you don't compile XML, it is being read as-is. Saving it and re-opening the window works just fine.)
quote: Originally posted by Flippy
Actually all I need is one window, roughly the size of the PNG image created, displaying the PNG image. Perhaps a button to close it, but that's not even a requirement. What controls am I looking at? In C# or VB I would use a picturebox, but there doesn't seem to be one..?
You're going to need a window with an ImageElement and a ButtonControl.
You'll want to set the image on the ImageElement in the interface XML to some kind of place-holder image ("Loading" or something alike) and then change the image dynamically with PlusWnd::ImageElmt_SetImageFile.
Another interesting thing you might want to use: if you simply give your button "BtnCancel" as Id, Plus! will automatically recognise it as a close button (unless you override this behaviour and add your own event handling for the button of course).
As for resizing the window according to the size of the loaded image, you're going to need a Win32 API call using Interop.Call() to SetWindowPos (in user32.dll) and set the width and height of the window. This will require some calculations to retrieve the size needed to display the image correctly but I'm sure that with a little creativity and some help from these forums, you'll be able to get this right!
If you have any question, search the forums first to make sure whether it has already been answered and if it's not, feel free to ask here!
RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 12:23 PM
Thanks.
At the moment, I'm just following the example in the documentation. I have been able to show the window in the Initialize event, but it won't show up in any other event...
I need it to show up after the latex is done converting to a png file, so I used this code:
jscript code: // -------------
// Show LaTeX in separate window
// -------------
var pngFile = folder + "\\file1.png";
if (fso.FileExists(pngFile))
{
var wnd = MsgPlus.CreateWnd("Windows.xml", "WndTest");
}
(This is in the OnEvent_ChatWndReceiveMessage event btw)
Nothing shows up.
I figured there might be something wrong with my file check (is there?), so I tried it without that... Still nothing. No window shows up.
What am I doing wrong? I can't see any mention of this in the documentation...?
RE: Basic Questions - LaTeX by Matti on 06-17-2009 at 01:49 PM
First of all, make sure that the FileExists block really works the way it should. Try to place a Debug.Trace() call inside it and see if you get the message in the debug window. Also make sure that the Interface Tester (link in previous post) gives you no errors about your interfaces.
Other than that, I see no reason why it shouldn't work if you have a valid window.
RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 02:41 PM
I've tried it without the FileExists block too, but still no window. When I place the wnd = MsgPlus.CreateWnd line in the Initialize event it shows up fine
EDIT
Nevermind, I got it. Apparently an error occured a few lines before this part, so anything after that stopped. I got the window now... All it does is say "hello" though, so now on to the ImageElement stuff... Can you recommend me any script that uses this, so I can see an example?
RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 03:07 PM
EDIT
Nevermind, got it
Another question: can I use an outside editor to edit the jscript files? This one is starting to piss me off, sorry It's really good for a 'simple' editor embedded into Plus!, but the one in Visual Studio for example is much better... I just spent 10 minutes figuring out why my code was wrong, and it was just a forgotten capital letter lol...
However, this works pretty good where I can just save the file and it will restart, so I can immediately try it again... How does that work if I use Visual Studio?
RE: Basic Questions - LaTeX by CookieRevised on 06-17-2009 at 05:54 PM
1) You don't need any batchfile.
You already use the Shell.Exec function so you know how to use it. With that same function you can simply perform your 2 steps needed to create a PNG right from the scripting language. So instead of executing a batch file which executes some other command line tools on its turn, why not simply execute the two command line tools directly with the proper parameters using the Shell object?
However, you can also use the Shell.Run for that. The reason it didn't worked at first is because you didn't used the function properly (you used it asyncroniously and thus it returned immediatly, thus before the PNG was created). For more information see the Windows Script Documentation > Index > 'Run method'.
Also remember to always add the proper path strings to the filenames (and enclose them in quotes if you use those files as parameters).
2) Don't use the WScript.Sleep() function!!!! This function will actually halt execution and will stop Messenger for a few milliseconds which can cause all sorts of bad things. WScript.Sleep() is acceptable in standalone scripts which you run in Windows, but certainly not in an integrated scripting language.
Instead learn to use timers (see the Plus! Scripting documentation).
Or, use Shell.Run as I said in previous point. In that way you don't need to wait for the function to finish since the Run method has that build in by using a boolean parameter (see Windows Script Documention). However, I do recommend using Shell.Exec, but as you have noticed it requires more programming and the proper use of timers.
But if you don't know how to use timers at this point, it is better to stick to the syncronious Shell.Run method.
-----
3) About the inline editor;
Yes, you can use any editor you like since the scripts are simply open-source text files. But the integrated editor is not as limited as you think. There are a few options which will greatly help you. When you use an external editor you wont have those options or you need to constantly switch between windows.
a) Show the debug window below the editor. In that way you immediatly see if everything is ok and if there is an error you'll see immediatly on which line and what the error is.
b) Intellisense: Just like in the Visual Studio editor there is a IntelliSense option which shows you possible function names.
c) Collapsable functions (outlining), line numbering
d) When you save a script from the inline editor it is immediatly restarted. However, there is a registry option for Messenger Plus! which will also restart the script whenever something has changed in its source. In that way you could edit your script in an external editor and whenever you save the source the script is restarted in Messenger Plus!.
See http://www.msgpluslive.net/help/registry/ and look for the ScriptDebugReloadOnChange setting.
So, first turn on debugging mode:
Plus! > Preferences & Options > General > Scripts > Enable debugging options
Then in the inline scripting editor go to the Options menu and turn on all the available options.
All in all I do recommend learning to use the inline editor though. Because especially debugging will be a lot easier and you don't need to switch between windows all the time.
3)4) There is an Interface Tester application, also made by Patchou. Using that tool you can immediatly see how your own created window will look like. You can download the Interface Tester here: http://www.msgpluslive.net/scripts/browse/9/Tools...Script-Developers/
RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 06:14 PM
1) I've tried running the commands directly, but it won't work. The reason is that the commands I'm using ("latex <file>" for example) don't work if the <file> is any full path (such as "C:\Test\file.tex"). The file needs to be relative (such as "file.tex").
Of course, for that to work, the current directory needs to be the directory in which the file is located. So I need to use the "cd <dir>" command to set this directory.
If I run the latex command separately, I cannot use the cd command (as far as I know), and hence it won't work.
Unless you can see another way?
2) Yeah, I realized that. It doesn't even do anything actually since WScript wasn't even any defined object. It gave me an error about that but I didn't notice it before. I removed it now.
3) I agree that the editor is not limited, especially not for an embedded editor. In fact, I know these types of editors pretty well, as I've used a few of them to make other applications. I am assuming it is a third party editor (it looks alot like the Quantum Whale editor, or the ActiPro (or something) editor), or did Patchou write it completely from scratch? If so, he should look into selling it lol. The editors I mentioned sell for about $500.
I know about the Outlining and Intellisense too, but the Intellisense seems to be pretty rare. It only shows up when I use objects such as 'MsgPlus. ...'. It doesn't show up when I try to call a function or something like that.
For example, the following script does not show Intellisense at the ___ location:
jscript code: function someFunction(name, age)
{
return "Your name is " + name + " and you are " + age + " years old.";
}
function someRandomFunction()
{
var x = someFunction( ___ )
}
If I load this code in Visual Studio, as soon as I type "s", it shows me "someFunction()" in the list. I press "(" and it completes it to "someFunction(" and then tells me it is expecting the "name" variable. It also shows me clearly that it expects two arguments.
If I type this in the Plus! editor, Intellisense doesn't show up at all...
Maybe I'm just too used to C# or VB.NET, where Intellisense pretty much lets you write the code without touching the keys, but it doens't seem very helpful here.
Of course, Visual Studio has all the same features too, except for the debugging thing... That does seem helpful, although I suppose I could just keep the debugging window open (I don't have a dual monitor setup for nothing ), that won't be much of a problem.
3) You already had a nr 3
Thanks for mentioning it though I'll check it out.
RE: Basic Questions - LaTeX by CookieRevised on 06-17-2009 at 06:36 PM
1) You're sure it doesn't allow absolute file names? In some cases it might be needed to use short path names instead of long path names. Or sometimes it requires you to enclose the file in quotes, and other times it explicitly doesn't.... Or maybe use a better converter
And you sure you didn't made the easy to make mistake of not doubling up the slashes? This is required in JScript. eg:
wrong: someFunction("C:\mydir\mycommand.exe")
correct: someFunction("C:\\mydir\\mycommand.exe")
If it indeed doesn't work with absolute file names, you could still execute the stuff in one go since the command line in Windows allows you to enter multiple commands on one line (using the & character). So you could still use the CD command before the LATEX command. eg: oShell.Run("CD c:\\blahblah & LATEX -someparameter")
Another possebility is using piping. This is where (simulated human) input is redirected to the command. This might even also safe you from first creating an input file.
eg: oShell.Run("echo $blahblah | C:\\mydir\\latex.exe")
(The $blahblah stuff will of course be the wrong syntax as it should be the same thing as when you manually type the stuff, but it's just an example of the principle using the echo command and piping (|) the output)
Then there is also maybe the possebility to use redirecting (using the < or > symbols) on the command line (though this does require a tex file).
Anyways, I'm sure it is possible to do everything in one go by using the proper DOS command line, without the use of any external files and batch files. The only question is how this LATEX tool exactly works and finding the proper syntax.
Therefor, can you provide a download link from where you got this LATEX command line tool? Then we can look into it and maybe give you the best solution. Or maybe even zip this latex command together with an example tex file and attach it to a post.
2) If you keep on using oShell.Exec, you do need to use timers (in order to check if the process has finished - oExec.Status != 0). Otherwise the function is executed asyncroniously and further code will run before the function has finished.
3) - Patchou writes all his stuff himself from scratch.
- Yes, IntelliSense in the inline editor only works for the build in Plus! functions and events (unfortunatly).
3) oops 4)
RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 07:38 PM
1) I am probably doing something wrong, as I don't know much about command line commands at all... However, even if I try it manually (eg, open cmd.exe) and then use the command "latex C:\Test\file.tex" or with quotes, double quotes, I've tried everything, but for some reason whenever I do this, it keeps looking in some random folder of the latex installation.
The installation I'm using is just MikTex, probably the most used in windows. It comes with the latex and dvipng command line commands. I'm sure there are others out there that allow me to do it in one go however.
But now the question... Why? Does it really matter that much that I use a batch file? Why go through all this trouble of piping etc, if I can just fire up a batch file? I'm not trying to sound like I know it better lol (cause i dont) but I'm just asking, maybe there's an important reason...
And the two commands on one line, didn't know that, I might use that than, thanks!
2) I thought so, as I am now running into the problem. As soon as I show the window that should show the latex png image, it is actually showing the old equation. It seems that the png file is shown before it is created (it already existed from my previous tests of course), so it is showing the old png file. I'll look into timers, thanks.
3) Well, then a big compliment for that. Believe me, I've tried, and failed hehe. Perhaps I can place a feature request? I am really missing the comment/uncomment selection, and possibly the format selection features. The comment/uncomment selection feature would insert (or remove) a comment (//) before each selected line, allowing users to quickly comment out pieces of code.
The format selection is not very hard to implement either I think since the language has a pretty easy construct (not like the language I had to create a parser for... eugh).
Those features would really make it more complete. Of course, more Intellisense would be a real improvement too, but I realize that is probably too much to ask, since it requires parsing the code completely. And if you're going that way, you might as well create your own scripting language hehe...
RE: RE: Basic Questions - LaTeX by CookieRevised on 06-17-2009 at 08:27 PM
quote: Originally posted by Flippy
But now the question... Why? Does it really matter that much that I use a batch file? Why go through all this trouble of piping etc, if I can just fire up a batch file? I'm not trying to sound like I know it better lol (cause i dont) but I'm just asking, maybe there's an important reason...
Simplicity. And thus a lot less prone to errors and stuff. It might seem 'more trouble' but it actually isn't.
You could ask the same thing ("why?") the oher way around:
Why using a lot of code, doing a lot of stuff, requiring external files, etc if you can simply do it in 1 very readable line of code?
Or why do people always try to write short and efficient code or improve their code when you can also do it the long way around using all sorts of unneeded and/or depricted stuff....
quote: Originally posted by Flippy
And the two commands on one line, didn't know that, I might use that than, thanks!
The DOS command line is actually a hell of lot more powerful than most people know...
quote: Originally posted by Flippy
3) Perhaps I can place a feature request?
of course, by all means do! Create a new thread in Msgplus! General Talk.
quote: Originally posted by Flippy
And if you're going that way, you might as well create your own scripting language hehe...
Actually... The JScript engine in Plus! already contains a lot of added functions and events specific for Plus! and Messenger. That is what makes Plus! scripting so powerful. It isn't just JScript (since you can't do much in pure JScript in this regards), it is JScript on steriods
For example timers, which are not available in pure JScript, you can also use any Windows API you like, etc... Making it extremely powerful (and just as dangerous as any other language).
RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 08:32 PM
Of course, the one line DOS command is much better. But I was talking about the piping etc, which seems to be alot more trouble than a single DOS command
I wanted to try the Run command, with the boolean you mentioned to make it synchronous, but I can't find the documentation for it. The Windows scripting guide I download won't work, every page shows as 'page not found' for some reason Ive tried downloading it numerous times, there must be something wrong with the file on their end I guess... Could you tell me how to use the Run command synchronously?
In the mean time I'm looking at user timers. It doens't seem very complicated, I might get it this way too.
RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 08:38 PM
Meh, I can't get it using timers either... Whatever I try, I always end up with a while loop that basically does the same thing I had before (the Sleep function).
How do I use the timers for this?
RE: Basic Questions - LaTeX by NanaFreak on 06-17-2009 at 09:02 PM
quote: Originally posted by Flippy
Meh, I can't get it using timers either... Whatever I try, I always end up with a while loop that basically does the same thing I had before (the Sleep function).
How do I use the timers for this?
look in the scripting documentation under Objects Reference > MsgPlus Object > Functions
RE: Basic Questions - LaTeX by CookieRevised on 06-17-2009 at 09:27 PM
You use piping and redirecting as an alternative in case the DOS tool you use doesn't support the proper parameters (like paths in filenames, etc).
----------
The reason why you get a "page not found" is not because of a damaged file or faulty download, but because your Windows is propbably not up to date or is set to block certain file content.
Also make sure you first download the file and then open it (so don't open it directly from the download dialog in MSIE as it will block the contents by default when the file is opened directly from the download).
see here:
http://geekswithblogs.net/evjen/archive/2006/06/29/83567.aspx
or here:
http://www.helpscribble.com/chmnetwork.html
Everything is also recapped here:
Silentdragon's reply to Official Scripting Documentation doesn't work.
----------
In regards to timers, see the Plus! Scripting documentation. Timers are event driven, you don't need any loop at all.
----------
PS, quickly looking at http://docs.miktex.org/manual/texfeatures.html#includedirectory
I see there is a command line parameter "-include-directory=dir".
Then there is also an output directory parameter:
http://docs.miktex.org/manual/texfeatures.html#outputdirectory
etc...
So there sure are a lot more possebilities and at first sight it looks like you can do everything from one command line using only the LATEX command and the proper parameters to create the DVI file.
And by very quickly skimming over the docs I found there are also some commands you can use inside a tex file to run other latex related things, so it might even be possible to also integrate the convertion to PNG in that same TEX file, dunno.
----------
So, everything boils down to reading the documentations of the stuff you wanna use. This means the docs for MikTeX, The Plus! Scripting Docs, and the Windows Script Docs.
RE: Basic Questions - LaTeX by Flippy on 06-17-2009 at 10:01 PM
Alright, the docs now work, thanks for that
I got the Run command to work, including the -include-directory switch and -output-directory switch. So I have been able to run the latex command without the use of the cd command, great!
But, it appears the dvipng command does not use these switches. It reports several fatal errors there...
So, I tried to use the & symbol to string the three commands (cd, latex, dvipng) together:
jscript code: var cmd = "cd " + path + " & " +
"latex file.tex & " +
"dvipng -T tight -x 1200 -z 9 file.dvi";
Debug.Trace("Executing command: \"" + cmd + "\".");
var oShell = new ActiveXObject('WScript.Shell');
oShell.Run(cmd, 0, true);
oShell = null;
Since the debugger tells me the command exactly, I tried it manually, simply pasting it in the cmd window. And it worked perfectly fine. Created the dvi and the png file!
But... The script errors on the Run command. It tells me it's an unknown error, error code -2147024894 (which googling found nothing).
The debugger output is this (dutch I know, but many of you seem to be from belgium so you might understand):
code: Executing command: "cd C:\Program Files\Messenger Plus! Live\Scripts\MSNLaTeX & latex file.tex & dvipng -T tight -x 1200 -z 9 file.dvi".
> Fout gedetecteerd in regel 100 van "MSNLaTeX.js": <onbekende fout>.
(Code: -2147024894)
> Fout gedetecteerd in "OnEvent_ChatWndReceiveMessage".
(Code: -2147352567)
The command itself cannot be the problem as it works when I use it manually... What's going on?
RE: Basic Questions - LaTeX by foaly on 06-17-2009 at 10:42 PM
quote: Originally posted by Flippy
> Fout gedetecteerd in regel 100 van "MSNLaTeX.js": <onbekende fout>.
What is on line 100?
RE: Basic Questions - LaTeX by CookieRevised on 06-18-2009 at 01:42 AM
You could debug that code yourself by stripping down the command line and testing it part by part... starting with the CD command...
Doing this it shows two things:
- You get the error because you start your command line with an internal DOS command (the CD command). Apparently you can't use the Run method to run an internal DOS command since the Run method does not start a DOS interpreter on its own.
The reason normal programs work is because they are executables. An internal DOS command isn't an executable, but is actually part of the DOS interpreter.
This can be solved by starting the interpreter yourself like so:
cmd /c cd c:\blahblah
- Second, you forgot to enclose long path and file names with quotes:
cd "c:\Program Files\Messenger Plus!\etc"
So, your command line in the script should be:
jscript code: var cmd = "cmd /c cd \"" + path + "\" & " +
"latex file.tex & " +
"dvipng -T tight -x 1200 -z 9 file.dvi";
And that will work...
However, for testing and debugging purposes you could temporarly do two things:
- change "cmd /c" to "cmd /k". This will keep the command window open and gives you the chance to actually see and check the output (more info on this if you type cmd /? in the interpreter). You must type "exit" to close the window and continue the script!
- change the second parameter of the Run method to 1, so the command window isn't hidden.
Thus for testing purposes, you could use:
jscript code: var cmd = "cmd /k cd \"" + path + "\" & " +
"latex file.tex & " +
"dvipng -T tight -x 1200 -z 9 file.dvi";
var oShell = new ActiveXObject('WScript.Shell');
oShell.Run(cmd, 1, true);
oShell = null;
and when everything works ok, you change it to:
jscript code: var cmd = "cmd /c cd \"" + path + "\" & " +
"latex file.tex & " +
"dvipng -T tight -x 1200 -z 9 file.dvi";
var oShell = new ActiveXObject('WScript.Shell');
oShell.Run(cmd, 0, true);
oShell = null;
PS: however, note that using the CD command to work around the dvipng limitation (you are absolutly sure you can't provide absolute paths in some way to dvipng, or set the input path to the script folder?) could cause a failure in case the script (and Plus!) wasn't installed on the default Windows drive.
The command "CD C:\blahblah" will not change the current drive to C. It will only change the path on the C-drive. So, if the current drive is D, the whole command line will fail again.
This is also easly solved by simply adding the command "C:" right before the "CD" command:
cmd /c C: & CD "c:\blahblah" & etc...
or:
jscript code: var cmd = "cmd /c " + path.substring(0, 2) + " & cd \"" + path + "\" & " +
"latex file.tex & " +
"dvipng -T tight -x 1200 -z 9 file.dvi";
This also applies in the same way if you use batch files or whatever though!. So you see, in the end, and to come back to your question of "why?", if you want to make things bug proof, using an absolute path name and using the proper command line parameters is much easier and way more efficient and shorter than using batch files and trying to work around all sorts of stuff like external files. (Provided the tools do support the needed parameters of course. Otherwise you are forced to use a workaround. But in that case you still should use the most efficient workaround - which batch files are certainly not).
RE: Basic Questions - LaTeX by Flippy on 06-18-2009 at 11:29 AM
Wow thanks, I learned something new again
I've got it nearly done now. The latex png is created and shows in a window.
Only thing left now is to resize the window depending on the size of the image.
I have been trying first to simply resize the window, without caring for the size of the image yet. I have very limited experience with API calls from VB/C#. I'm looking at the SetWindowPos function now, and apparently it needs the window handle (wnd.Handle, correct?), the X, Y, width and height obviously, and then two other parameters I can't really understand.
First, there's the hWndInsertAfter parameter, which I assume is to determine whether the window is going to be on top, bottom etc of the z-order. OK. I want it to be on top (but not topmost), so apparently I need the HWND_TOP value.
Now... What is the value I need to use??!! That is the main reason I always have trouble with API programming. The MSDN entries never list the actual values for their constants?! How am I supposed to know what value to use?
I'm probably missing something... In the end I googled HWND_TOP SetWindowPos and found the value by accident in some obscure site... Why can't the MSDN page simply tell me what the value is?
Oh well, in the end I got it working with this:
jscript code: Interop.Call("user32.dll", "SetWindowPos", wnd.Handle, 0, 1, 1, 800, 600, 0x0040);
It puts the window in the top-left corner, with a size of 800x600. Great.
Now a problem: The ImageElement displaying the equation is not resized. Do I need to resize that manually, too? Or can I use some kind of docking/anchoring to ensure that it stretches with the window when resized?
And, how can I find the size (not in kb, but width/height) of the PNG image? Ideally I want the window to be resized accordingly.
Finally, is it possible to find the location of the current chatwindow, so I can have the equation window pop up to the side, bottom, top, of it (depending on where the window is)?
I could calculate the 'free area' to the sides of the window, and then determine whether to display it to the right or left of it, to ensure that it does not pop up out of view.
If I can just find the location and size of the chat window that would be enough.
Oh yeah one more thing, there seems to be a bug in the editor. For the ImageElmt_SetImageFile function to accept a full path ("C:\Program Files\...") instead of a path relative to the Images folder, I needed to insert a backslash before the file path, so in my case this becomes:
jscript code: wnd.ImageElmt_SetImageFile("EquationImage", "\\" + path + "\\file1.png");
The problem is that the editor (or at least the syntax highlighting) thinks that "+ path + ..." is part of the string.
When I run this code it works fine however, so it must be just a bug in the syntax highlighting.
Here's a screenshot to clarify the problem:
RE: Basic Questions - LaTeX by NanaFreak on 06-18-2009 at 11:43 AM
quote: Originally posted by Flippy
The problem is that the editor (or at least the syntax highlighting) thinks that "+ path + ..." is part of the string.
When I run this code it works fine however, so it must be just a bug in the syntax highlighting.
Here's a screenshot to clarify the problem:
[Image: 144hfb.jpg]
yes this is a known bug of the scripting window... and its very annoying but patchou is too lazy to fix it =p
RE: Basic Questions - LaTeX by Matti on 06-18-2009 at 12:03 PM
quote: Originally posted by NanaFreak
quote: Originally posted by Flippy
The problem is that the editor (or at least the syntax highlighting) thinks that "+ path + ..." is part of the string.
When I run this code it works fine however, so it must be just a bug in the syntax highlighting.
Here's a screenshot to clarify the problem:
[Image: 144hfb.jpg]
yes this is a known bug of the scripting window... and its very annoying but patchou is too lazy to fix it =p
And that's exactly why I do my coding in an external editor!
RE: Basic Questions - LaTeX by Flippy on 06-18-2009 at 01:29 PM
Ok, I found Javascript code to find the size of an image, but it doesn't work in jscript
javascript code: var newImg = new Image();
newImg.src = imgSrc;
var height = newImg.height;
var width = newImg.width;
But 'Image' isn't recognized... I'm plowing on
RE: Basic Questions - LaTeX by Matti on 06-18-2009 at 01:52 PM
That's because JavaScript differs from JScript in some points. In this case, the Image object is available in JavaScript but not in JScript.
Unfortunately, you'll have to dive into advanced code to get the size of the image. Graphical stuff is done by the GDI and GDI+ libraries from Windows, and those are not the easiest to work with.
As tester and interface designer of the upcoming Screenshot Sender 5, I know that it has a nice script class to work with GDI+ functions. I'll ask matty, the creator of SS5, if it's okay for him if you get this part of the code. I'll let you know when I got a reply.
RE: Basic Questions - LaTeX by Flippy on 06-18-2009 at 03:32 PM
Wow, so many thanks for that!
I had it working a minute ago, and wanted to show a screenshot, but now I changed something in the latex document ('preamble') and it's now printing page numbers too, making the image very large for no reason lol
Just gotta find out how to get rid of the page number and I can show a screenshot...
Ok got it
Screenshots:
Inline equation (meaning, equations and text simultaneously):
Displaystyle equation (meaning, only one equation, no text):
RE: Basic Questions - LaTeX by Matti on 06-18-2009 at 03:56 PM
Now that's really cool! Are you planning to publicly release that?
RE: Basic Questions - LaTeX by Flippy on 06-18-2009 at 04:21 PM
Sure, once it's ready
It's far from ready at the moment. One thing that is still bugging me is that it doesn't work when you keep the little window open. I'm assuming that the png file is in use that way, and the dvipng command does not work properly. In each case, the new png image is not created, so you have to close the window before you can receive a new file...
I'm still looking for a way to solve this. One solution I thought of would be to delete the PNG as soon as it is loaded into the ImageElement. Of course, that only works if the ImageElement has it loaded into memory, or is still using it. If it's still using it I won't be able to delete it...
Another solution, which I already tried, was to delete the PNG before creating the new image. However, I keep getting an "access denied" error whenever I try that (even when the window is closed!). I haven't figured out why yet... Perhaps I need to set the wnd object to null or something, maybe it's still in memory, using the png file?
Anyway... Once that works, I want the window to pop up to the side of the chat window (if there is room). I need to find the size and location of the chat window (which I assume can be done with an API call) and then determine where there's room to place the window. If there's no room I'll just display it near the top of the chat window, which would usually be on top of the chat history, so you can still see the most recent messages...
Once's that is done, I actually want to make it a bit more complex, lol. I could have some kind of history where multiple images are stored into the history, and you can browse back. Otherwise, if your chat buddy is typing too fast, and types two equations after each other, you may miss one
Oh well, let's get this basic stuff working first hehe...
RE: Basic Questions - LaTeX by Matti on 06-18-2009 at 05:33 PM
Hmm, here is an idea:
- Generate a random number for each created PNG file, e.g. "845217623.png". This will prevent any writing access trouble.
- When the PNG is created, create the window and load the image. Store the loaded image's file name in a global object, indexed by the window's handle.
- When the window is destroyed, the file name is looked up from the global object and the image is deleted.
I think that'll work. I know it's not the most elegant solution, but I'll leave the challenge for you to play around with this idea.
As for finding out the position of the chat window, have a look at GetWindowRect (user32). Create a RECT memory structure using Interop.Allocate(), make the function fill it and use the data in the RECT structure to figure out where to place your window.
@matty: Okay, it'll work just fine with the time too. I don't know whether you want to delete those created images after closing the window, so I'll leave my comment untouched just in case.
RE: Basic Questions - LaTeX by matty on 06-18-2009 at 05:36 PM
My suggestion is the following:
js code: var oGdip = new Gdip();
if ( oGdip.Initialize() === true ) {
>>> oGdip.ConvertImage( 'C:\\myImage.png', 'C:\\myImage'+new Date().getTime()+'.jpg', 'JPG', 75 );<<<
Debug.Trace( oGdip.GetImageDimensions( 'C:\\myImage.jpg' ) );
oGdip.Uninitialize();
} else Debug.Trace ( 'An error occured while initializing Gdi+' );
Then you can load the new JPG file and overwrite the PNG. Then you can create as many windows as needed as long as you load the latest image
RE: Basic Questions - LaTeX by Flippy on 06-18-2009 at 05:47 PM
Well, I got it working by simply closing the window before generating the new PNG file.
If I ever want to try my more advanced idea (multiple images in history) then I probably need to have a look at your suggestions. But for now, this works fine.
I also don't want a separate window for every equation, that would become very unwieldy.
Right now I'm looking at some error trapping in the command line part. If the latex code is invalid for some reason, the compiler does not continue and my conversation window locks up. I am pretty sure I can retrieve some error information from the later compiler though, so it won't be a problem to check for that. The problem is I don't know yet how But I'll get it hehe...
RE: Basic Questions - LaTeX by Flippy on 06-18-2009 at 06:11 PM
Well first of all getting the window size... I tried it, but I don't really know how to use the Allocate function. It wants to know the size in bytes, but how do I know? The Rect structure seems to store 4 long integers (= 4 * 4 bytes???) so I used 16, but I also tried 4, and basically any other logical value I could think of lol... But the left, top, etc properties all come back as 'undefined':
jscript code: // Get chat window size
var wndRect = Interop.Allocate(4);
Interop.Call("user32.dll", "GetWindowRect", ChatWnd.Handle, wndRect);
Debug.Trace("Left: " + wndRect.left +
", Top: " + wndRect.top +
", Right: " + wndRect.right +
", Bottom: " + wndRect.bottom);
Output:
code: Left: undefined, Top: undefined, Right: undefined, Bottom: undefined
Anything else I need to do to make this work?
Also, I forgot I also need the size of desktop (client screen size), excluding task bar if possible. Any API call for that?
RE: Basic Questions - LaTeX by Spunky on 06-18-2009 at 07:11 PM
js code: // Get chat window size
var wndRect = Interop.Allocate(4);
Interop.Call("user32.dll", "GetWindowRect", ChatWnd.Handle, wndRect);
Debug.Trace("Left: " + wndRect.left +
", Top: " + wndRect.top +
", Right: " + wndRect.right +
", Bottom: " + wndRect.bottom);
Should be more like:
js code: // Get chat window size
var wndRect = Interop.Allocate(16);
Interop.Call("user32.dll", "GetWindowRect", ChatWnd.Handle, wndRect);
Debug.Trace("Left: " + wndRect.ReadDWORD(0) +
", Top: " + wndRect.ReadDWORD(4) +
", Right: " + wndRect.ReadDWORD(8) +
", Bottom: " + wndRect.ReadDWORD(12));
Might be .ReadWORD instead of DWORD though... not used them in a while.
RE: Basic Questions - LaTeX by Matti on 06-18-2009 at 07:22 PM
Ah, it seems like you ran into the same problem every developer goes through when learning to work with Interop.Allocate and memory structures. No worries, I've had the same thing as well.
Let's have a look at the RECT structure as defined by MSDN:
code: typedef struct _RECT {
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT;
We first need to know the size of this structure. To do this, we make the sum of the size each individual type takes. In this case, we have 4 LONG values and each LONG takes 4 bytes, so we get 16 bytes as size.
js code: var wndRect = Interop.Allocate(16);
We can then call GetWindowRect to fill this structure for us.
js code: Interop.Call("user32.dll", "GetWindowRect", ChatWnd.Handle, wndRect);
As you can see, you were doing pretty well in fact!
Now we want to read the individual pieces of the memory structure. Unlike C++, a Plus! script doesn't actually "know" what structure you created, so you'll have to find out where your data is yourself and what type it is.
For instance, if we want to read the value for the left position. Looking back at the MSDN structure definition, we find that this is the first element in the structure, and that it's a LONG of 4 bytes. This means that we have to read the DWORD on position 0 (zero) to get the left position:
js code: var wndLeft = wndRect.ReadDWORD(0);
On to the next element: the top position. This is the second element in the structure, thus there is one LONG before it. This means we can find it on position 4 in our structure, also as a DWORD. The right position will be 4 bytes further on position 8 and the bottom position will be at position 12.
js code: var wndTop = wndRect.ReadDWORD(4);
var wndRight = wndRect.ReadDWORD(8);
var wndBottom = wndRect.ReadDWORD(12);
And there you have it! You just read a RECT structure!
For the OOP fans here, you can also do this with a nice object:
js code: var objRect = {
left: wndRect.ReadDWORD(0),
top: wndRect.ReadDWORD(4),
right: wndRect.ReadDWORD(8),
bottom: wndRect.ReadDWORD(12)
};
[offtopic]
Blah, I've been beaten again while writing this way too long post.
Hah, at least I beat you here!
[/offtopic]
RE: Basic Questions - LaTeX by Flippy on 06-18-2009 at 07:23 PM
Ahhhh, that makes sense. Thanks, it seems to work so far!
RE: Basic Questions - LaTeX by Flippy on 06-18-2009 at 08:10 PM
I'm having a bit of trouble with my window at the moment... I'm trying to make it a look a biter nicer, because the png image is only exactly as large as the equation, so there is no 'border' around the equation, making it hard to read sometimes.
I thought I could simply use another ImageElement beneath the equation image, pure white, which was a bit bigger than the equation ImageElement. And while I'm at it (I thought), I can also add a third ImageElement, completely black, exactly 1 pixel offset form the white image (and two pixels larger), making it appear like a small black border.
The XML is this:
xml code: <Interfaces xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Window Id="EquationWindow" Version="1">
<Attributes>
<Caption>LaTeX</Caption>
</Attributes>
<TitleBar>
<Title>
<Text>LaTeX</Text>
</Title>
</TitleBar>
<Position Width="200" Height="160">
<IsAbsolute>true</IsAbsolute>
<Resizable Allowed="BothSides">
<MinWidth>200</MinWidth>
<MinHeight>160</MinHeight>
</Resizable>
</Position>
<DialogTmpl>
<BottomBar Style="Plain">
<RightControls>
<Control xsi:type="ButtonControl" Id="BtnCancel">
<Position Left="0" Top="0" Width="50"/>
<Caption>Close</Caption>
</Control>
</RightControls>
</BottomBar>
</DialogTmpl>
<Elements>
<Element xsi:type="ImageElement" Id="BlackBG">
<Position Left="4" Top="4" Width="192" Height="122">
<IsAbsolute>true</IsAbsolute>
<Anchor Horizontal="LeftRightFixed" Vertical="TopBottomFixed"/>
</Position>
<Image>
<Name>blackBG</Name>
<Mosaic>ResizeToFit</Mosaic>
</Image>
</Element>
<Element xsi:type="ImageElement" Id="WhiteBG">
<Position Left="5" Top="5" Width="190" Height="120">
<IsAbsolute>true</IsAbsolute>
<Anchor Horizontal="LeftRightFixed" Vertical="TopBottomFixed"/>
</Position>
<Image>
<Name>whiteBG</Name>
<Mosaic>ResizeToFit</Mosaic>
</Image>
</Element>
<Element xsi:type="ImageElement" Id="EquationImage">
<Position Left="8" Top="8" Width="184" Height="114">
<IsAbsolute>true</IsAbsolute>
<Anchor Horizontal="LeftRightFixed" Vertical="TopBottomFixed"/>
</Position>
<Image>
<Name>loading</Name>
</Image>
</Element>
</Elements>
</Window>
</Interfaces>
And the window, when using the Interface Tester, looks like this:
I'm noticing a few things:
1. The black and white images appear to be exactly the size I saved them in. Shouldn't the <Mosaic>ResizeToFit</Mosaic> tag make sure they are stretched, so they fill the window as I tell them?
2. The window is not resizable at all, even though I tell it too. Maybe this is just not possible in the Interface Tester? I've no idea...
3. The black border on the left is two pixels instead of one, indicating that the white image is actually two pixels offset from the black one, even though I'm telling it to be only one pixel apart.
4. When I run my script, the window looks like this:
Where has everything gone??
RE: Basic Questions - LaTeX by CookieRevised on 06-19-2009 at 09:14 AM
A few thoughts, which probably go against a bit of what people have suggested so far:
1) To read the width and height of a PNG you don't need any big library or other JScript files from other scripts. That's extreme overkill, especially if you're going to use something like the GDI+ lib from ScreenShot Sender, for just reading image sizes.
a) So, you can do this using GDI+. This is actually not so super hard once you get the basics. So you certainly do not need the full blown library (like the one from the otherwise excellent Screenshot Sender script). All you need is:
jscript code: function GetImageWidthHeight(sFilePath) {
var lGdiplusToken = Interop.Allocate(4);
var lGdiplusStartupInput = Interop.Allocate(16);
lGdiplusStartupInput.WriteDWORD(0, 1); // Set GDI version 1
var lReturn = Interop.Call('GDIPLUS.DLL', 'GdiplusStartup', lGdiplusToken, lGdiplusStartupInput, null);
if (lReturn === 0) {
var hFile = Interop.Allocate(4);
var PNGwidth = Interop.Allocate(4);
var PNGheight = Interop.Allocate(4);
if (Interop.Call('GDIPLUS.DLL', 'GdipLoadImageFromFile', sFilePath, hFile) === 0) {
Interop.Call('GDIPLUS.DLL', 'GdipGetImageWidth', hFile.ReadDWORD(0), PNGwidth);
Interop.Call('GDIPLUS.DLL', 'GdipGetImageHeight', hFile.ReadDWORD(0), PNGheight);
Interop.Call('KERNEL32.DLL', 'CloseHandle', hFile.ReadDWORD(0));
}
Interop.Call('GDIPLUS.DLL', 'GdiplusShutdown', lGdiplusToken.ReadDWORD(0));
PNGwidth = PNGwidth.ReadDWORD(0);
PNGheight = PNGheight.ReadDWORD(0);
Debug.Trace('The image size is: ' + PNGwidth + 'x' + PNGheight);
}
}
b) Or do it even more simpler. Simply read the proper bytes from the file directly. This is very possible for PNGs since the IHDR chunk (containing the image specs) must always be the first chunk in the PNG so you don't need to bother about parsing chunks and a whole big set of functions to handle a PNG.
The width and height will always be at offset 16 and 20 (and they are both 4 bytes long = DWORD, and they are in Big Endian order):
jscript code: function GetPNGWidthHeight(sFilePath) {
var hFile = Interop.Call('kernel32.dll', 'CreateFileW', sFilePath, 0x80000000 /* GENERIC_READ */, 1 /* FILE_SHARE_READ */, 0, 3 /* OPEN_EXISTING */, 0, 0);
if (hFile !== -1) {
var lpBuffer = Interop.Allocate(24);
var lpBytesRead = Interop.Allocate(4);
var lReturn = Interop.Call('KERNEL32.DLL', 'ReadFile', hFile, lpBuffer, 24, lpBytesRead, 0);
Interop.Call('KERNEL32.DLL', 'CloseHandle', hFile);
if (lReturn !== 0 && lpBytesRead.ReadDWORD(0) === 24) {
// Important: PNGs have a Big Endian byte order
var PNGwidth = lpBuffer.GetAt(16) << 24 | lpBuffer.GetAt(17) << 16 | lpBuffer.GetAt(18) << 8 | lpBuffer.GetAt(19)
var PNGheight = lpBuffer.GetAt(20) << 24 | lpBuffer.GetAt(21) << 16 | lpBuffer.GetAt(22) << 8 | lpBuffer.GetAt(23);
Debug.Trace('The image size is: ' + PNGwidth + 'x' + PNGheight);
}
lpBytesRead.Size = 0;
lpBuffer.Size = 0;
}
}
Of course, this function is specific for PNGs.
c) PS: If you're going to use the script only on your own computer. Or at least on a computer which doesn't have some special DBCS encoding needs (like Japanese, etc) you could use an even simpler and very short method to read the binary data from a file. But since that will not work for everyone, it is not so trustable...
-------------------------
2) You need to take into consideration that multiple people can send you multiple Latex strings at the same time.
So you do need to have a system where the current loaded image is unique. As you already noticed, when a file is loaded it is locked and can't be overwritten.
Matti's suggestion is the best one and the only one which is always going to work in every situation.
Matty's suggestion of copying the PNG to JPG is not going to work because of the same reason why you get the 'access denied' error in the first place. You can't copy over a locked file either. Second, I really do not recommend converting a PNG to a JPG as that will reduce the quality.
-------------------------
3) If you don't want multiple windows pop up each time, maybe you could create a kind of history in that window, where the user can click a button and go back to the previous (or next) image. Upon closing the window, you delete all the used files from disk (again by using the method from Matti - that is with an I, not a Y - god, this is confusing ).
-------------------------
EDIT: don't create a black image and a white image underneath the graphic to have borders. You will have stretching problems when you resize the window/images. Instead draw a real border (with a fix thickness so it does not stretch) around the graphic you're showing. And/or take a look at the 'FigureElement' in the Plus! Scripting Documentation for this (you can assign a border to it, it can show an image, and you could even define (white) margins).
Plus! Scripting Documentation > Contents > XML Schemas Reference > Interface Windows > Schema Documentation > FigureElement
RE: Basic Questions - LaTeX by Matti on 06-19-2009 at 01:43 PM
@CookieRevised: Okay, I understand that you don't need a complete script file with a fully functional class to just read the dimensions of the image.
But heck, as a script developer I prefer a clear overall structure so I know where I can easily find my functions. And when I group related methods in a single library file, it's much easier to extend that with extra methods since you'll probably already have a decent base to built on.
I have to admit I didn't know about how to read the size of the PNG binary - thanks for that! Still, I think it's more of a hassle when you need different functions for different image formats (PNG, JPG, GIF) when you can use a universal image library which does just the same.
Ah well, it appears to be a matter of your own taste... Maybe I'm spoiled by all the OOP goodness the most recent frameworks and programming languages offer (.NET, PHP, jQuery,...). Maybe I don't want to dive into dealing with bytes and binaries any more. Well, then so be it!
RE: Basic Questions - LaTeX by Flippy on 06-19-2009 at 02:31 PM
I thought of a different way, but I'm not sure yet which one I'm going to use. The fact that I need to take into account multiple people sending me latex simultaneously is indeed a problem at the moment.
A possible fix would be to store one equation image per chat window (or per contact name possibly, doesn't really matter I guess). This way, I could open a new image window for every contact person talking to me.
If I missed an equation, I would either have to build in the history images, but I was also thinking about another way. The latex code will still be in the chat history (well, just the messages that have been sent since you last opened the window I mean), and I could create some kind of /latex command, where the user can just type /latex and then copy/paste the latex code he wants to see. It could then open a separate window, just for him, and show him the latex.
Something like this could also be used to 'preview' your latex. I find that, especially with large latex codes, I usually make small mistakes, like forgetting a brace } or something, which makes the whole equation wrong.
What do you guys think is best?
RE: RE: Basic Questions - LaTeX by CookieRevised on 06-19-2009 at 10:24 PM
[VERY LONG TRAIN OF THOUGHTS... TUUUT TUUUT... GOING ON A SIDETRACK]
quote: Originally posted by Matti
@CookieRevised: Okay, I understand that you don't need a complete script file with a fully functional class to just read the dimensions of the image.
But heck, as a script developer I prefer a clear overall structure so I know where I can easily find my functions. And when I group related methods in a single library file, it's much easier to extend that with extra methods since you'll probably already have a decent base to built on.
I have to admit I didn't know about how to read the size of the PNG binary - thanks for that! Still, I think it's more of a hassle when you need different functions for different image formats (PNG, JPG, GIF) when you can use a universal image library which does just the same.
If you need to read several formats, and if you are going to use several functions, then yes, absolutely. But in this case you only going to read the size of a PNG, nothing else.
quote: Ah well, it appears to be a matter of your own taste... Maybe I'm spoiled by all the OOP goodness the most recent frameworks and programming languages offer (.NET, PHP, jQuery,...). Maybe I don't want to dive into dealing with bytes and binaries any more. Well, then so be it!
a matter of taste, absolutely... but...
I'm all for libraries myself, but only if you're going to use several functions of that library. Otherwise it is a complete and utter waste of space if you only need 1 function, especially in a language like JScript where nothing is compiled and every unused function stays in. Unlike compiled programs where it doesn't matter if you add a 50MB big library of code, only the used code is going to be compiled and included (in most languages) anyways.
But if you only need one function (like here) and you write in a language like JScript then I would rather export that one function to the script instead of adding a 20Kb big library (so to speak) which would simply sit there doing nothing.
I'm 100% certain that if you compare the GDI+ version of the readsize function with the GDI library in Screenshot Sender, that the code would be almost 100% the same (since there is no other way to do it/program it with GDI). And that single function can be use for any image format GDI+ supports.
And most importantly in this case here (IMHO) is that exporting, and also revising, functions from libraries can be an extremely big learning tool. Otherwise you'll keep on using functions without knowing what they actually do or how they do it. A lot of problems and questions arise from the fact that if you (too) often use libraries (even if you only need 1 thing) and if you get too dependant on them, you don't learn anything new or don't have a clue what to improve or bugfix... That's one of the major reasons why I like to include only the 1 or 2 functions from a library in my snippets/examples to people, instead of simply suggesting to use lib x or y with 50 functions. Especially if the OP shows that he/she is more than happy to learn new things and how to do stuff... Other people might even benefit too (like you just said that you now learned how to use the ReadFile APIs to read binary data).
But in the end, a matter of taste, absolutely, since I personaly like to know what wrapper X does or what functions wrapper Y actually use (in case I come across a similar but slightly different problem which I can't fix with out-of-the-box-functions). And hence, I reflect that to the people I try to help too... As it is more satisfying (too me at least) that people learn something new from your examples, than that they are 'helped' with a already written stuff which they need to copy (without even looking at it).
[/ARRIVED AT STATION ]
RE: Basic Questions - LaTeX by sabian2008 on 07-30-2009 at 03:38 PM
Has this project died??? I was so excited about it =(
RE: Basic Questions - LaTeX by Flippy on 07-30-2009 at 04:36 PM
For now, yes I'm afraid it has. I lost interest, just didn't get it to work as I wanted it.
I've attached the source so anyone can play around with it. I must warn you that I started making changes a while back without really finishing them, so it might not work anymore out of the box.
Feel free to use it however you like.
(You must have MikTex installed for this to work!)
RE: Basic Questions - LaTeX by sabian2008 on 08-07-2009 at 01:01 AM
What a shame. I would continue it of course, but my programming skills don't get past Fortan (which is far from a flexible language) so i must confess i am really dissapointed.
Anyway, thanks for putting so much effort to it anyway. Cya
|