What happened to the Messenger Plus! forums on msghelp.net?
Shoutbox » MsgHelp Archive » Messenger Plus! for Live Messenger » Scripting » Basic Questions - LaTeX

Pages: (6): « First « 1 2 3 4 [ 5 ] 6 » Last »
Basic Questions - LaTeX
Author: Message:
Flippy
Junior Member
**


Posts: 29
35 / Male / Flag
Joined: Jun 2009
O.P. RE: Basic Questions - LaTeX
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?

This post was edited on 06-18-2009 at 06:13 PM by Flippy.
06-18-2009 06:11 PM
Profile E-Mail PM Find Quote Report
Spunky
Former Super Mod
*****

Avatar

Posts: 3658
Reputation: 61
36 / Male / Flag
Joined: Aug 2006
RE: Basic Questions - LaTeX
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.
<Eljay> "Problems encountered: shit blew up" :zippy:
06-18-2009 07:11 PM
Profile PM Find Quote Report
Matti
Elite Member
*****

Avatar
Script Developer and Helper

Posts: 1646
Reputation: 39
32 / Male / Flag
Joined: Apr 2004
RE: Basic Questions - LaTeX
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! :D

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! :D

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! :P
[/offtopic]

This post was edited on 06-18-2009 at 07:23 PM by Matti.
Plus! Script Developer | Plus! Beta Tester | Creator of Countdown Live | Co-developer of Screenshot Sender 5

Found my post useful? Rate me!
06-18-2009 07:22 PM
Profile E-Mail PM Web Find Quote Report
Flippy
Junior Member
**


Posts: 29
35 / Male / Flag
Joined: Jun 2009
O.P. RE: Basic Questions - LaTeX
Ahhhh, that makes sense. Thanks, it seems to work so far!
06-18-2009 07:23 PM
Profile E-Mail PM Find Quote Report
Flippy
Junior Member
**


Posts: 29
35 / Male / Flag
Joined: Jun 2009
O.P. RE: Basic Questions - LaTeX
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:
[Image: 33or8di.jpg]

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:
[Image: vhzqyr.jpg]
Where has everything gone??
06-18-2009 08:10 PM
Profile E-Mail PM Find Quote Report
CookieRevised
Elite Member
*****

Avatar

Posts: 15517
Reputation: 173
– / Male / Flag
Joined: Jul 2003
Status: Away
RE: Basic Questions - LaTeX
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 :p).

-------------------------

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

This post was edited on 06-19-2009 at 09:28 AM by CookieRevised.
.-= A 'frrrrrrrituurrr' for Wacky =-.
06-19-2009 09:14 AM
Profile PM Find Quote Report
Matti
Elite Member
*****

Avatar
Script Developer and Helper

Posts: 1646
Reputation: 39
32 / Male / Flag
Joined: Apr 2004
RE: Basic Questions - LaTeX
@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! :P
Plus! Script Developer | Plus! Beta Tester | Creator of Countdown Live | Co-developer of Screenshot Sender 5

Found my post useful? Rate me!
06-19-2009 01:43 PM
Profile E-Mail PM Web Find Quote Report
Flippy
Junior Member
**


Posts: 29
35 / Male / Flag
Joined: Jun 2009
O.P. RE: Basic Questions - LaTeX
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?
06-19-2009 02:31 PM
Profile E-Mail PM Find Quote Report
CookieRevised
Elite Member
*****

Avatar

Posts: 15517
Reputation: 173
– / Male / Flag
Joined: Jul 2003
Status: Away
RE: RE: Basic Questions - LaTeX
[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! :P
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 :p]

This post was edited on 06-19-2009 at 10:34 PM by CookieRevised.
.-= A 'frrrrrrrituurrr' for Wacky =-.
06-19-2009 10:24 PM
Profile PM Find Quote Report
sabian2008
New Member
*


Posts: 2
Joined: Jul 2009
RE: Basic Questions - LaTeX
Has this project died??? I was so excited about it =(
07-30-2009 03:38 PM
Profile E-Mail PM Find Quote Report
Pages: (6): « First « 1 2 3 4 [ 5 ] 6 » Last »
« Next Oldest Return to Top Next Newest »


Threaded Mode | Linear Mode
View a Printable Version
Send this Thread to a Friend
Subscribe | Add to Favorites
Rate This Thread:

Forum Jump:

Forum Rules:
You cannot post new threads
You cannot post replies
You cannot post attachments
You can edit your posts
HTML is Off
myCode is On
Smilies are On
[img] Code is On