Shoutbox

Interface Writer | [release] 3.0 | 22/08/2010 - 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: Interface Writer | [release] 3.0 | 22/08/2010 (/showthread.php?tid=90773)

Interface Writer | [release] 3.0 | 22/08/2010 by whiz on 05-25-2009 at 02:55 PM

Features

  • basically, it writes windows for you :P
  • can be saved as an XML file, or a copy/paste compatible source code
  • load existing interfaces and edit them
  • import, save as and save copy functions for interface files
  • unlimited windows, controls and elements
  • graphically build windows with the simple builder tool
  • view interface files without needing the editor
  • user-friendly - just double-click to add or edit windows, controls or elements
  • full validation of file paths, window IDs and control IDs

New in this Version
  • added: bottom bar support (including placing controls in them)
  • added: comments for controls/elements
  • added: controls/elements can have negative positions
  • added: custom double-click action for window manager
  • added: load/save options for evaluator (debug)
  • added: multiple control/element editors
  • added: preset manager - add/insert/remove presets from one place
  • added: recovery options (backups saved when changes are made)
  • added: sort windows, controls or elements alphabetically on demand
  • added: status bar - information on add/edit/remove actions, saving, etc.
  • added: support for Interface Tester application
  • changed: dialog and debugging classes have been rewritten for stability
  • changed: help guide covers window, control and element managers globally
  • changed: new windows with existing IDs prompts to overwrite
  • fixed: controls and elements are lost after windows are renamed
  • fixed: controls and elements cannot be added to renamed windows
  • fixed: debug options don't disable properly
  • fixed: recent files list only displays one item
  • fixed: editing a pasted window (with original intact) edits both simultaneously
  • fixed: selection button remains enabled after certain actions
  • fixed: window, control and element managers refused to cancel renaming

Screenshot (click to enlarge)
[Image: ?image=Interface+Writer]

To-do List
  • control enabled/visible options - won't be too hard, just not got round to it yet
  • multiple items on the clipboard (currently, one window, control and element maximum)
  • control/element builder (not sure how to do - want to be able to "draw" onto a window)
  • support for bottom bar controls (when enabled in a window)
  • sidebar on window manager - possibly with a child window

Download Options

RE: BETA - Interface Writer 1.0! by matty on 05-25-2009 at 03:16 PM

FnSaveMethods.js:

function SaveInterface() {}

js code:
var TextFile = FileSO.OpenTextFile(FilePath, 2);
Should be:
js code:
var TextFile = FileSO.OpenTextFile(FilePath, 2, true, -1 /*UNICODE*/);

RE: BETA - Interface Writer 1.0! by Spunky on 05-25-2009 at 03:26 PM

quote:
Originally posted by whiz
Known Issues
no validation of numbers (for example, it will allow "text" as a valid height measurement)
no validation of matching ID's (for example, two controls with the name "EdtTest")

If you need help with these, PM me and I will help ;)
RE: Interface Writer | [beta] 1.0 by whiz on 05-25-2009 at 03:31 PM

quote:
Originally posted by matty

FnSaveMethods.js:

function SaveInterface() {}

js code:
var TextFile = FileSO.OpenTextFile(FilePath, 2);
Should be:
js code:
var TextFile = FileSO.OpenTextFile(FilePath, 2, true, -1 /*UNICODE*/);


Thanks for that.  I've fixed it, and I'll re-upload it in a moment...



quote:
Originally posted by Spunky
quote:
Originally posted by whiz
Known Issues
no validation of numbers (for example, it will allow "text" as a valid height measurement)
no validation of matching ID's (for example, two controls with the name "EdtTest")

If you need help with these, PM me and I will help ;)

I can probably do the first one, but I'm not sure about the second.  Would something like this work:

js code:
for (var X in WndLstId)
{
    if (!objWnd.GetControlText("EdtId") == WndLstId[X])
    {
        // save code here...
    }
}

EDIT: actually, I've changed my mind.  I don't think I can do the first one either.  ;)
RE: BETA - Interface Writer 1.0! by Matti on 05-25-2009 at 04:02 PM

Those issues aren't that hard to solve! :P

  • Validation of numbers (for example, it will allow "text" as a valid height measurement)
    js code:
    var sFoo = "85.1";
    var nFoo = 1 * sFoo; //Attempt a string to number conversion
    if( isNaN(nFoo) ) nFoo = 0; //Failed, set to some default value or ignore the declaration
  • Validation of matching IDs (for example, two controls with the name "EdtTest")
    js code:
    var sTestId = "BtnTest"; //Control ID to test
    var bIsUniqueId = true; //Boolean to hold the result

    for( var i in WndLstId ) { //Loop through the control IDs
        if( WndLstId[i] == sTestId ) { //Check if this control ID matches the test ID
            //We have a match!
            bIsUniqueId = false; //Set the result to false
            break; //End the loop (we know it's not unique now)
        }
    }
    //Now make use of bIsUniqueId for further processing

RE: BETA - Interface Writer 1.0! by Spunky on 05-25-2009 at 04:07 PM

quote:
Originally posted by Matti
Those issues aren't that hard to solve! :P
  • Validation of numbers (for example, it will allow "text" as a valid height measurement)
    js code:
    var sFoo = "85.1";
    var nFoo = 1 * sFoo; //Attempt a string to number conversion
    if( isNaN(nFoo) ) nFoo = 0; //Failed, set to some default value or ignore the declaration
  • Validation of matching IDs (for example, two controls with the name "EdtTest")
    js code:
    var sTestId = "BtnTest"; //Control ID to test
    var bIsUniqueId = true; //Boolean to hold the result

    for( var i in WndLstId ) { //Loop through the control IDs
        if( WndLstId[i] == sTestId ) { //Check if this control ID matches the test ID
            //We have a match!
            bIsUniqueId = false; //Set the result to false
            break; //End the loop (we know it's not unique now)
        }
    }
    //Now make use of bIsUniqueId for further processing



Has already sent a PM, but both solutions are very similar to mine so I feel a bit better now :D
RE: BETA - Interface Writer 1.0! by Matti on 05-25-2009 at 04:11 PM

quote:
Originally posted by Spunky
Has already sent a PM, but both solutions are very similar to mine so I feel a bit better now :D
Hah, great minds think alike! :D
RE: Interface Writer | [beta] 1.0 by whiz on 05-25-2009 at 05:15 PM

The "Add Window/Control" validators work fine, but the "Change Window/Control" validators don't seem to recognise if the ID matches another window/control's ID - even though those bits use the same validation method...

js code:
// works fine :)
function OnWndWriterAddWndEvent_EditTextChanged(objWnd, strControlId)
{
    if (objWnd.GetControlText("EdtId") == "" || objWnd.GetControlText("EdtTitle") == "" || objWnd.GetControlText("EdtWidth") == "" || objWnd.GetControlText("EdtHeight") == "")
    {
        Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 0);
    }
    else
    {
        if (isNaN (objWnd.GetControlText("EdtWidth") * 1) == true || isNaN (objWnd.GetControlText("EdtHeight")) == true)
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 0);
        }
        else
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 1);
            for (var X in WndLstId)
            {
                if (WndLstId.length > 0 && objWnd.GetControlText("EdtId") == WndLstId[X])
                {
                    Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 0);
                }
                else
                {
                    Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 1);
                }
            }
        }
    }
}

// gets it wrong :(
function OnWndWriterChangeWndEvent_EditTextChanged(objWnd, strControlId)
{
    if (objWnd.GetControlText("EdtId") == "" || objWnd.GetControlText("EdtTitle") == "" || objWnd.GetControlText("EdtWidth") == "" || objWnd.GetControlText("EdtHeight") == "")
    {
        Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 0);
    }
    else
    {
        if (isNaN (objWnd.GetControlText("EdtWidth") * 1) == true || isNaN (objWnd.GetControlText("EdtHeight")) == true)
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 0);
        }
        else
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 1);
            for (var X in WndLstId)
            {
                if (WndLstId.length > 1 && objWnd.GetControlText("EdtId") == WndLstId[X])
                {
                    if (objWnd.GetControlText("EdtId") == WndLstId[WndLstTStSel])
                    {
                        Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 1);
                    }
                    else
                    {
                        Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 0);
                    }
                }
                else
                {
                    Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 1);
                }
            }
        }
    }
}

// works fine :)
function OnWndWriterAddControlEvent_EditTextChanged(objWnd, strControlId)
{
    if (objWnd.GetControlText("EdtId") == "" || objWnd.GetControlText("EdtLeft") == "" || objWnd.GetControlText("EdtDown") == "" || objWnd.GetControlText("EdtWidth") == "" || objWnd.GetControlText("EdtHeight") == "" || objWnd.Combo_GetCurSel("CmbType") == -1 || objWnd.Combo_GetCurSel("CmbType") == 0)
    {
        Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 0);
    }
    else
    {
        if (isNaN (objWnd.GetControlText("EdtLeft") * 1) == true || isNaN (objWnd.GetControlText("EdtDown") * 1) == true || isNaN (objWnd.GetControlText("EdtWidth") * 1) == true || isNaN (objWnd.GetControlText("EdtHeight")) == true)
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 0);
        }
        else
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 1);
            for (var X in WndCtrlId[WndLstTStSel])
            {
                if (WndCtrlId[WndLstTStSel].length > 0 && objWnd.GetControlText("EdtId") == WndCtrlId[WndLstTStSel][X])
                {
                    Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 0);
                }
                else
                {
                    Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 1);
                }
            }
        }
    }
}

// works fine :)
function OnWndWriterAddControlEvent_ComboSelChanged(objWnd, strControlId)
{
    if (objWnd.GetControlText("EdtId") == "" || objWnd.GetControlText("EdtLeft") == "" || objWnd.GetControlText("EdtDown") == "" || objWnd.GetControlText("EdtWidth") == "" || objWnd.GetControlText("EdtHeight") == "" || objWnd.Combo_GetCurSel("CmbType") == -1 || objWnd.Combo_GetCurSel("CmbType") == 0)
    {
        Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 0);
    }
    else
    {
        if (isNaN (objWnd.GetControlText("EdtLeft") * 1) == true || isNaN (objWnd.GetControlText("EdtDown") * 1) == true || isNaN (objWnd.GetControlText("EdtWidth") * 1) == true || isNaN (objWnd.GetControlText("EdtHeight")) == true)
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 0);
        }
        else
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 1);
            for (var X in WndCtrlId[WndLstTStSel])
            {
                if (WndCtrlId[WndLstTStSel].length > 0 && objWnd.GetControlText("EdtId") == WndCtrlId[WndLstTStSel][X])
                {
                    Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 0);
                }
                else
                {
                    Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 1);
                }
            }
        }
    }
}

// gets it wrong :(
function OnWndWriterChangeControlEvent_EditTextChanged(objWnd, strControlId)
{
    if (objWnd.GetControlText("EdtId") == "" || objWnd.GetControlText("EdtLeft") == "" || objWnd.GetControlText("EdtDown") == "" || objWnd.GetControlText("EdtWidth") == "" || objWnd.GetControlText("EdtHeight") == "" || objWnd.Combo_GetCurSel("CmbType") == -1 || objWnd.Combo_GetCurSel("CmbType") == 0)
    {
        Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 0);
    }
    else
    {
        if (isNaN (objWnd.GetControlText("EdtLeft") * 1) == true || isNaN (objWnd.GetControlText("EdtDown") * 1) == true || isNaN (objWnd.GetControlText("EdtWidth") * 1) == true || isNaN (objWnd.GetControlText("EdtHeight")) == true)
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 0);
        }
        else
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 1);
            for (var X in WndCtrlId[WndLstTStSel])
            {
                if (WndCtrlId[WndLstTStSel].length > 1 && objWnd.GetControlText("EdtId") == WndCtrlId[WndLstTStSel][X])
                {
                    if (objWnd.GetControlText("EdtId") == WndCtrlId[WndLstTStSel][WndCtrlTStSel])
                    {
                        Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 1);
                    }
                    else
                    {
                        Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 0);
                    }
                }
                else
                {
                    Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 1);
                }
            }
        }
    }
}

// gets it wrong :(
function OnWndWriterChangeControlEvent_ComboSelChanged(objWnd, strControlId)
{
    if (objWnd.GetControlText("EdtId") == "" || objWnd.GetControlText("EdtLeft") == "" || objWnd.GetControlText("EdtDown") == "" || objWnd.GetControlText("EdtWidth") == "" || objWnd.GetControlText("EdtHeight") == "" || objWnd.Combo_GetCurSel("CmbType") == -1 || objWnd.Combo_GetCurSel("CmbType") == 0)
    {
        Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 0);
    }
    else
    {
        if (isNaN (objWnd.GetControlText("EdtLeft") * 1) == true || isNaN (objWnd.GetControlText("EdtDown") * 1) == true || isNaN (objWnd.GetControlText("EdtWidth") * 1) == true || isNaN (objWnd.GetControlText("EdtHeight")) == true)
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 0);
        }
        else
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 1);
            for (var X in WndCtrlId[WndLstTStSel])
            {
                if (WndCtrlId[WndLstTStSel].length > 1 && objWnd.GetControlText("EdtId") == WndCtrlId[WndLstTStSel][X])
                {
                    if (objWnd.GetControlText("EdtId") == WndCtrlId[WndLstTStSel][WndCtrlTStSel])
                    {
                        Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 1);
                    }
                    else
                    {
                        Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 0);
                    }
                }
                else
                {
                    Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), 1);
                }
            }
        }
    }
}


RE: BETA - Interface Writer 1.0! by Matti on 05-25-2009 at 05:41 PM

Well, you're not implementing our sample code properly. :P
You shouldn't re-enable the control when one item in the loop doesn't match the ID to test simply because you won't have all used IDs matching that one ID, you have to check whether there is at least one match.

js code:
        if (isNaN (objWnd.GetControlText("EdtLeft") * 1) == true || isNaN (objWnd.GetControlText("EdtDown") * 1) == true || isNaN (objWnd.GetControlText("EdtWidth") * 1) == true || isNaN (objWnd.GetControlText("EdtHeight")) == true)
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 0);
        }
        else
        {
>>>            var bCanChange = true;<<<
>>>            var sEdtId = objWnd.GetControlText("EdtId");<<<
            for (var X in WndLstId)
            {
>>>                if (WndLstId.length > 1 && sEdtId == WndLstId[X] && X == WndLstTStSel)<<<
                    {
>>>                        bCanChange = false;<<<
>>>                        break;<<<
                    }
                }
            }
>>>            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), bCanChange);<<<
        }
As you can see, you don't need an else-block anywhere, you simply check three things:
  1. Check whether there are IDs in the array.
  2. Check whether the currently chosen test ID matches the key name of the current item in the loop.
  3. Check whether this item is currently being edited.
When these three conditions are fulfilled for one item in the loop, we can say that the chosen ID is not unique and thus bCanChange has to be set to false in order to disable the edit button.
When these conditions are never fulfilled, bCanChange will never change from its original value (true) and the button will be enabled.

Oh, on a side note: try to store some of the GetControlText calls in a variable inside your functions when you use them very often. It's good practice to take off the load of the API to get the control text every time and simply retrieve the value from a variable - the control text won't change anyway while executing the event function (and you don't want it to change either).
RE: BETA - Interface Writer 1.0! by vaccination on 05-25-2009 at 05:41 PM

...so no one's noticed that it fails at the first hurdle yet?

Script fails to create xml files.

code:
<-- Start file creation. -->
> Attempting to create file "C:\Users\vaccination\Desktop\Windows.xml"...
Error: Object expected (code: -2146823281)
       File: WndWriterCreateFile.js. Line: 70.
Function OnWndWriterCreateFileEvent_CtrlClicked returned an error. Code: -2147352567

Line 70 =
jscript code:
else if (FileC(objWnd.GetControlText("EdtPath") + "\\" + objWnd.GetControlText("EdtName") + ".xml", true))

..FileC doesn't exist...

----

Also, might want to read the corect folder from the registry, or at least use MsgPlus.ScriptFilesPath instead of just assuming it's "\Program Files\Plus!.." because it isn't always, for instance, on x64 machines.

There's a lot of other improvements you could make too, for instance instead of writing the xml to a text file and manually adding all the nodes with TextFile.WriteLine like you are, try using the XML DOM instead.

You should also include a preview feature to make the script actually useful, and should be relatively easy to add in.

Oh and you've used a few Plus! resources in your script - such as imgfind, imgsave, imgcode etc - and still included the files in the package, you could just call the resources directly from Plus!.
RE: BETA - Interface Writer 1.0! by CookieRevised on 05-25-2009 at 06:24 PM

Nice idea for a script and it has potential (y)... but...


quote:
Originally posted by Matti
Validation of numbers (for example, it will allow "text" as a valid height measurement)
js code:
var sFoo = "85.1";
var nFoo = 1 * sFoo; //Attempt a string to number conversion
if( isNaN(nFoo) ) nFoo = 0; //Failed, set to some default value or ignore the declaration

You don't need to multiply it with 1.
The next code will work just as good because the function isNaN() will already attempt to convert the variable to a number:
js code:
var sFoo = "85.1";
if( isNaN(sFoo) ) nFoo = 0

In any case, whiz, check your code more carefully so you don't forget crucial stuff or make small mistakes. Although it wouldn't result in a wrong check (because of the above), you forgot to multiply the "EdtHeight" with 1 when you implemented the code posted by Matti:
code:
if (isNaN(objWnd.GetControlText("EdtWidth") * 1) == true || isNaN(objWnd.GetControlText("EdtHeight") * 1) == true)
So in this case you are lucky that you didn't needed the *1 at all, but in other cases such mistakes might result in hard to find bugs...
So, the above line can be written as:
code:
if (isNaN(objWnd.GetControlText("EdtWidth")) || isNaN(objWnd.GetControlText("EdtHeight")))


Also:
Remember to take the casing of strings into consideration when you compare strings. Code like:
js code:
for( var i in WndLstId ) {
>>>    if( WndLstId[i] == sTestId ) {<<<
        bIsUniqueId = false;
        break;
    }
}
...will fail if the Id of one control is "BtnTest" and the other control "Btntest".
You must convert the strings to the same casing (eg: lowercase) when comparing.

Even if the control id is case sensitive and using "BtnTest" for one control and "Btntest" for another is allowed, it is still a good idea to still dissallow it in your script because it is not recommended and not good practice and as a result such things _will_ eventually result in errors in the used scripts. So:
js code:
if( WndLstId[i][b].toLowerCase() === sTestId.toLowerCase() ) {
PS: also notice the use of === (is identical) instead of == (is equal). Learn more about the difference here.

----

The above are all small details but can make a very big difference. So, a very big tip: before adding new stuff and/or features, revise your entire script very carefully as it contains many (small but crucial) errors and potential bugs, like vaccination already said.

;)

RE: Interface Writer | [beta] 1.0 by whiz on 05-27-2009 at 05:37 PM

quote:
Originally posted by Matti
Well, you're not implementing our sample code properly. :P
You shouldn't re-enable the control when one item in the loop doesn't match the ID to test simply because you won't have all used IDs matching that one ID, you have to check whether there is at least one match.
js code:
        if (isNaN (objWnd.GetControlText("EdtLeft") * 1) == true || isNaN (objWnd.GetControlText("EdtDown") * 1) == true || isNaN (objWnd.GetControlText("EdtWidth") * 1) == true || isNaN (objWnd.GetControlText("EdtHeight")) == true)
        {
            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnAdd"), 0);
        }
        else
        {
>>>            var bCanChange = true;<<<
>>>            var sEdtId = objWnd.GetControlText("EdtId");<<<
            for (var X in WndLstId)
            {
>>>                if (WndLstId.length > 1 && sEdtId == WndLstId[X] && X == WndLstTStSel)<<<
                    {
>>>                        bCanChange = false;<<<
>>>                        break;<<<
                    }
                }
            }
>>>            Interop.Call("user32", "EnableWindow", objWnd.GetControlHandle("BtnChange"), bCanChange);<<<
        }
As you can see, you don't need an else-block anywhere, you simply check three things:
  1. Check whether there are IDs in the array.
  2. Check whether the currently chosen test ID matches the key name of the current item in the loop.
  3. Check whether this item is currently being edited.
When these three conditions are fulfilled for one item in the loop, we can say that the chosen ID is not unique and thus bCanChange has to be set to false in order to disable the edit button.
When these conditions are never fulfilled, bCanChange will never change from its original value (true) and the button will be enabled.

I have sorted that problem out now, thanks!  :)



quote:
Originally posted by vaccination
...so no one's noticed that it fails at the first hurdle yet?

Script fails to create xml files.

code:
<-- Start file creation. -->
> Attempting to create file "C:\Users\vaccination\Desktop\Windows.xml"...
Error: Object expected (code: -2146823281)
       File: WndWriterCreateFile.js. Line: 70.
Function OnWndWriterCreateFileEvent_CtrlClicked returned an error. Code: -2147352567

Line 70 =
jscript code:
else if (FileC(objWnd.GetControlText("EdtPath") + "\\" + objWnd.GetControlText("EdtName") + ".xml", true))

..FileC doesn't exist...

Ah, sorry.  I originally used a function for that, but I removed it.  I sorted that for the overwrite option, but not for the main writer.  Fixed!  :P

quote:
Originally posted by vaccination
Also, might want to read the corect folder from the registry, or at least use MsgPlus.ScriptFilesPath instead of just assuming it's "\Program Files\Plus!.." because it isn't always, for instance, on x64 machines.

There's a lot of other improvements you could make too, for instance instead of writing the xml to a text file and manually adding all the nodes with TextFile.WriteLine like you are, try using the XML DOM instead.

You should also include a preview feature to make the script actually useful, and should be relatively easy to add in.

Oh and you've used a few Plus! resources in your script - such as imgfind, imgsave, imgcode etc - and still included the files in the package, you could just call the resources directly from Plus!.

I know how to get the script's folder and registry path, but how can I get just the script base directory?



quote:
Originally posted by CookieRevised
Nice idea for a script and it has potential (y)... but...


quote:
Originally posted by Matti
Validation of numbers (for example, it will allow "text" as a valid height measurement)
js code:
var sFoo = "85.1";
var nFoo = 1 * sFoo; //Attempt a string to number conversion
if( isNaN(nFoo) ) nFoo = 0; //Failed, set to some default value or ignore the declaration

You don't need to multiply it with 1.
The next code will work just as good because the function isNaN() will already attempt to convert the variable to a number:
js code:
var sFoo = "85.1";
if( isNaN(sFoo) ) nFoo = 0

In any case, whiz, check your code more carefully so you don't forget crucial stuff or make small mistakes. Although it wouldn't result in a wrong check (because of the above), you forgot to multiply the "EdtHeight" with 1 when you implemented the code posted by Matti:
code:
if (isNaN(objWnd.GetControlText("EdtWidth") * 1) == true || isNaN(objWnd.GetControlText("EdtHeight") * 1) == true)
So in this case you are lucky that you didn't needed the *1 at all, but in other cases such mistakes might result in hard to find bugs...
So, the above line can be written as:
code:
if (isNaN(objWnd.GetControlText("EdtWidth")) || isNaN(objWnd.GetControlText("EdtHeight")))


Fixed.  None of them use it now.  ;)

quote:
Originally posted by CookieRevised
Also:
Remember to take the casing of strings into consideration when you compare strings. Code like:
js code:
for( var i in WndLstId ) {
>>>    if( WndLstId[i] == sTestId ) {<<<
        bIsUniqueId = false;
        break;
    }
}
...will fail if the Id of one control is "BtnTest" and the other control "Btntest".
You must convert the strings to the same casing (eg: lowercase) when comparing.

Even if the control id is case sensitive and using "BtnTest" for one control and "Btntest" for another is allowed, it is still a good idea to still dissallow it in your script because it is not recommended and not good practice and as a result such things _will_ eventually result in errors in the used scripts. So:
js code:
if( WndLstId[i][b].toLowerCase() === sTestId.toLowerCase() ) {
PS: also notice the use of === (is identical) instead of == (is equal). Learn more about the difference here.

Applied to all validators.  Thanks for the tip!  ;)
RE: BETA - Interface Writer 1.0! by roflmao456 on 05-27-2009 at 06:50 PM

Looks interesting..
* roflmao456 tries it out

edit: neat (Y)


RE: Interface Writer | [release] 1.2 by whiz on 05-27-2009 at 07:02 PM

Thanks!  ;)

Note to all: please post any bugs or errors you encounter!  :)


RE: BETA - Interface Writer 1.0! by matty on 05-27-2009 at 07:05 PM

How about some screenshots.


RE: BETA - Interface Writer 1.0! by vaccination on 05-27-2009 at 07:13 PM

Um...

code:
<-- Start file creation. -->
> Attempting to create file "C:\Users\vaccination\Desktop\Windows.xml"...
Error: File not found (code: -2146828235)
       File: WndWriterCreateFile.js. Line: 70.
Function OnWndWriterCreateFileEvent_CtrlClicked returned an error. Code: -2147352567


----

quote:
Originally posted by whiz
I know how to get the script's folder and registry path, but how can I get just the script base directory?

I don't think you read my post correctly, you read the registry* to get the script folders path. [or alternatively, if you get the current script folder path from msgplus.scriptfilefolder then just use substr(-<whatever>) to minus the unnecessary part.]

*hklm\software\patchou\messenger plus! live\scriptsdir

----

Also, you're *still* packing plus resources in the script that you can just call from Plus!.
RE: Interface Writer | [release] 1.2 by whiz on 05-27-2009 at 07:45 PM

quote:
Originally posted by vaccination
Um...

code:
<-- Start file creation. -->
> Attempting to create file "C:\Users\vaccination\Desktop\Windows.xml"...
Error: File not found (code: -2146828235)
       File: WndWriterCreateFile.js. Line: 70.
Function OnWndWriterCreateFileEvent_CtrlClicked returned an error. Code: -2147352567



I think I have fixed that now (I will re-upload the file in a moment)...

quote:
Originally posted by vaccination
quote:
Originally posted by whiz
I know how to get the script's folder and registry path, but how can I get just the script base directory?

I don't think you read my post correctly, you read the registry* to get the script folders path. [or alternatively, if you get the current script folder path from msgplus.scriptfilefolder then just use substr(-<whatever>) to minus the unnecessary part.]

*hklm\software\patchou\messenger plus! live\scriptsdir

So can I use "MsgPlus.ScriptFilesPath", and then remove the "\Interface Writer"?

quote:
Originally posted by vaccination
Also, you're *still* packing plus resources in the script that you can just call from Plus!.

I have removed unnecessary images from the directory, and replaced them in the Windows.xml file with the Messenger Plus! image versions.  Some, like the add/delete button images, I have left as-is because they're from the Windows Live Messenger resource extraction - they look better.  ;)
RE: Interface Writer | [release] 1.2 by whiz on 05-27-2009 at 08:05 PM

quote:
Originally posted by matty
How about some screenshots.

Done.  ;)  Click here...
RE: BETA - Interface Writer 1.0! by vaccination on 05-27-2009 at 09:28 PM

quote:
Originally posted by whiz

quote:
Originally posted by vaccination
quote:
Originally posted by whiz
I know how to get the script's folder and registry path, but how can I get just the script base directory?

I don't think you read my post correctly, you read the registry* to get the script folders path. [or alternatively, if you get the current script folder path from msgplus.scriptfilefolder then just use substr(-<whatever>) to minus the unnecessary part.]

*hklm\software\patchou\messenger plus! live\scriptsdir

So can I use "MsgPlus.ScriptFilesPath", and then remove the "\Interface Writer"?

Precisely. (Or a better way would be to just read the registry value IMO but whatever =p)
RE: Interface Writer | [release] 1.2 by whiz on 05-28-2009 at 03:26 PM

quote:
Originally posted by vaccination
Precisely. (Or a better way would be to just read the registry value IMO but whatever =p)

Then how do you do that?  ;)
RE: BETA - Interface Writer 1.0! by vaccination on 05-28-2009 at 03:59 PM

quote:
Originally posted by whiz
quote:
Originally posted by vaccination
Precisely. (Or a better way would be to just read the registry value IMO but whatever =p)

Then how do you do that?  ;)
Something like:
jscript code:
var aWshShell = new ActiveXObject("WScript.Shell");

//Read a reg key value:
var ScriptPath = aWshShell.RegRead("HKEY_LOCAL_MACHINE\\Software\\Patchou\\Messenger Plus! Live\\ScriptsDir");

RE: Interface Writer | [release] 1.2 by whiz on 05-28-2009 at 04:01 PM

quote:
Originally posted by vaccination
Something like:
jscript code:
var aWshShell = new ActiveXObject("WScript.Shell");

//Read a reg key value:
var ScriptPath = aWshShell.RegRead("HKEY_LOCAL_MACHINE\\Software\\Patchou\\Messenger Plus! Live\\ScriptsDir");


And that returns the root script directory?
RE: BETA - Interface Writer 1.0! by vaccination on 05-28-2009 at 04:07 PM

quote:
Originally posted by whiz
quote:
Originally posted by vaccination
Something like:
jscript code:
var aWshShell = new ActiveXObject("WScript.Shell");

//Read a reg key value:
var ScriptPath = aWshShell.RegRead("HKEY_LOCAL_MACHINE\\Software\\Patchou\\Messenger Plus! Live\\ScriptsDir");


And that returns the root script directory?
Try it and find out...
RE: Interface Writer | [release] 1.2 by whiz on 05-28-2009 at 04:12 PM

Works great, thanks!  ;)


RE: Interface Writer | [beta] 1.0 -> [release] 1.2 by mynetx on 06-14-2009 at 03:58 PM

I like this script very much.  In fact here is a suggestion I'd love to see:
Parse window XML of existing windows, and allow to edit them.


RE: Interface Writer | [release] 1.2 by whiz on 06-14-2009 at 04:16 PM

quote:
Originally posted by mynetx
I like this script very much.  In fact here is a suggestion I'd love to see:
Parse window XML of existing windows, and allow to edit them.
I thought about that, but I have no idea of how to read and edit existing XML files.  :S
RE: Interface Writer | [beta] 1.0 -> [release] 1.2 by mynetx on 06-14-2009 at 04:56 PM

Maybe the attached library gives you an idea.


RE: Interface Writer | [beta] 1.0 -> [release] 1.2 by SmokingCookie on 06-14-2009 at 05:34 PM

About the scripts' folder: I use this method:

JScript code:
function GetScriptFolder() {
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var ret = fso.GetFolder(MsgPlus.ScriptFilesPath + "\\..").Path;
    fso = null; // Clean up
    return ret;
}

Works for me..

EDIT::

Checking whether 'something' exists within an object:

JScript code:
var myObj = new Object();
myObj.someProperty = "Hello world!";

if("someProperty" in myObj) Debug.Trace("Exists!");
if("someOtherProperty" in myObj /* this is false; code won't be run */) Debug.Trace("Exists");

RE: Interface Writer | [beta] 1.0 -> [release] 1.2 by vaccination on 06-14-2009 at 10:04 PM

quote:
Originally posted by SmokingCookie
About the scripts' folder: I use this method:

JScript code:
function GetScriptFolder() {
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var ret = fso.GetFolder(MsgPlus.ScriptFilesPath + "\\..").Path;
    fso = null; // Clean up
    return ret;
}

Works for me..

Or you could do it the proper way...
RE: Interface Writer | [release] 1.2 by whiz on 06-15-2009 at 03:16 PM

quote:
Originally posted by mynetx
Maybe the attached library gives you an idea.
Umm...  I'm afraid I don't really understand that.  :S  All I get is that XML comes in nodes, and the script would read each "child" node of each "parent", and put it into the arrays (e.g. the first control ID of the first window into the WndCtrlIDs[0][0] variable).  But I have no idea how to do it...  :(
RE: Interface Writer | [beta] 1.0 -> [release] 1.2 by SmokingCookie on 06-15-2009 at 04:30 PM

Let me provide you with an example that may be useful to you.....

See attachment

Note that the provided code is untested. You'll have to implement your own way of handling the position, anchoring, attributes and control-specific stuff, but I think you'll be OK with this ;)


RE: Interface Writer | [release] 1.2 by whiz on 06-15-2009 at 06:27 PM

Umm... (well, I was about to say there was a problem with line 30, but I found the spelling mistake :))

code:
Function called: OnEvent_Initialize
Error: Object expected (code: -2146823281)
       File: __FnWindowParser.js. Line: 46.
Error: Object expected (code: -2146823281)
       File: __FnWindowParser.js. Line: 46.
Function OnEvent_Initialize returned an error. Code: -2147352567

Line 46:
js code:
if(ControlId in ret.Interface[WindowId].Controls[ControlType]) // ...

Is that what verifies if two control IDs match?  What is the object invovled?  :S

EDIT: there's a similar problem with the Element check as well:
code:
Error: Object expected (code: -2146823281)
       File: __FnWindowParser.js. Line: 61.
Error: Object expected (code: -2146823281)
       File: __FnWindowParser.js. Line: 61.
Function OnEvent_Initialize returned an error. Code: -2147352567

Line 61:
js code:
if(ElementId in ret.Interface[WindowId].Elements[ElementType]) // ...

RE: Interface Writer | [beta] 1.0 -> [release] 1.2 by SmokingCookie on 06-15-2009 at 07:51 PM

Yeah, that's the thingy that checks whether something exists within an object.

For the errors: I'll fix it tomorrow; I'm gonna go sleeping now |-)


RE: Interface Writer | [release] 1.2 by whiz on 06-15-2009 at 08:03 PM

quote:
Originally posted by SmokingCookie
For the errors: I'll fix it tomorrow; I'm gonna go sleeping now |-)
Fair enough, I need some sleep as well.  :P
RE: Interface Writer | [beta] 1.0 -> [release] 1.2 by SmokingCookie on 06-16-2009 at 12:17 PM

Have you slept well? :P

Anyway, here you go with a fix. I've left out the control/element typing. You can do that by retrieving the "xsi:type" attribute of a selected node (so K.item()). I've also included a prototype of my own JSON interpreter, but it does not return valid JSON yet. It's only to give you a basic idea of the object that has been created by parseFile().


RE: Interface Writer | [beta] 1.0 -> [release] 1.2 by Flippy on 06-17-2009 at 11:47 AM

I may be stupid lol, but how do I even use this? I installed the script, it says it's started in the preferences/options screen, but I have no idea how to use it lol... I don't see it anywhere?


RE: Interface Writer | [release] 1.2 by whiz on 06-17-2009 at 06:56 PM

quote:
Originally posted by SmokingCookie
Have you slept well? :P

Anyway, here you go with a fix. I've left out the control/element typing. You can do that by retrieving the "xsi:type" attribute of a selected node (so K.item()). I've also included a prototype of my own JSON interpreter, but it does not return valid JSON yet. It's only to give you a basic idea of the object that has been created by parseFile().
Ok, let's see.

js code:
var ControlsXPath = "//Interfaces/Window[@Id=\"" + WindowId + "\"]/Controls/Control";
var ElementsXPath = "//Interfaces/Window[@Id=\"" + WindowId + "\"]/Elements/Element";
// Define objects that contain the control types, subdevided into control/element IDs
ret.Interface[WindowId] = new Object();
ret.Interface[WindowId].Controls = new Object();
ret.Interface[WindowId].Elements = new Object();
1) Am I able to create my own, like this?  For example, to get the window title:
js code:
var CaptionsXPath = "//Interfaces/Window[@Id=\"" + WindowId + "\"]/Attributes/Caption";
var TitlesXPath = "//Interfaces/Window[@Id=\"" + WindowId + "\"]/TitleBar/Title/Text";
But...  it can't be enumerated:
js code:
var K = new Enumerator(xml.selectNodes(CaptionsXPath));
It's different, because the value isn't "<Item Parameter="Value">", but "<Item>Value</Item>".  How can I get that?

js code:
var K = new Enumerator(xml.selectNodes(ControlsXPath));
if(K.count() > 0) {
    for(; !K.atEnd(); K.moveNext()) {
        var ControlNode = K.item();
        var ControlId = ControlNode.getAttribute("Id");
        // Define an object for this control type (as in ButtonControl or StaticControl) that contains the actual control
        // Only done when necessary
        if(ControlId in ret.Interface[WindowId].Controls) {
            //[alert the user that there's 2 or more controls with the same ID]
            continue;
        }
        // You'll have to do your own stuff here
        ret.Interface[WindowId].Controls[ControlId] = "null" //[JScript control definition stuff]
    }
}
2a) If that gets a control ID, then I assume that getting the type uses the same method, replacing ".getAttribute("Id")" with ".getAttribute("xsi:type")", right?
2b) Would this work:
js code:
var K = new Enumerator(xml.selectNodes(ControlsXPath + "/Position"));
for(; !K.atEnd(); K.moveNext()) {
    var ControlNode = K.item();
    var ControlLeft = ControlNode.getAttribute("Left");
    // Define an object for this control type (as in ButtonControl or StaticControl) that contains the actual control
    // Only done when necessary
    if(ControlId in ret.Interface[WindowId].Controls) {
        //[alert the user that there's 2 or more controls with the same ID]
        continue;
    }
    // You'll have to do your own stuff here
    ret.Interface[WindowId].Controls[ControlId] = "null" //[JScript control definition stuff]
}

I apologise for so many questions, but this is a confusing topic for me...  :S

EDIT: yes, I slept well.  10 good hours.  :D



quote:
Originally posted by Flippy
I may be stupid lol, but how do I even use this? I installed the script, it says it's started in the preferences/options screen, but I have no idea how to use it lol... I don't see it anywhere?
Go to the Script Menu > "Interface Writer" > "Create a new interface...".  :)
RE: Interface Writer | [beta] 1.0 -> [release] 1.5 by CookieRevised on 06-22-2009 at 06:11 PM

Please update your first post in this thread with the new version instead of attaching it to a new post.

Not doing this will confuse a lot of people (not everybody checks every post in a thread for a new version) and will result in old versions being distributed.


RE: RE: Interface Writer | [beta] 1.0 -> [release] 1.5 by whiz on 06-27-2009 at 02:57 PM

quote:
Originally posted by CookieRevised
Please update your first post in this thread with the new version instead of attaching it to a new post.

Not doing this will confuse a lot of people (not everybody checks every post in a thread for a new version) and will result in old versions being distributed.
Done...  (added a link to the top to download it).
RE: Interface Writer | [beta] 1.0 -> [release] 1.5 by CookieRevised on 06-28-2009 at 01:16 AM

quote:
Originally posted by whiz
quote:
Originally posted by CookieRevised
Please update your first post in this thread with the new version instead of attaching it to a new post.

Not doing this will confuse a lot of people (not everybody checks every post in a thread for a new version) and will result in old versions being distributed.
Done...  (added a link to the top to download it).
ok, but it is way better to edit your first post and instead replace the old script with the new(est) version.
After that you can remove all the other attachments in your other posts, they aren't needed and people will still be able to download the wrong version.
(remember, not everybody reads an entire thread to know which version is which; mostly, if they see an attachment in a post (after they came directly to that post because they were referred to it fro manother thread), they probably think it is the latest version)...

If you have an update, do the same thing again. Simply replace the previous version with the new version in the first post. no reason to keep older (buggy) versions.

This is done in every other script thread and is the way most people expect it to be. And there can't be any mistakes either with that method.

Having a list of older versions is nice but it makes things much more complicated which isn't needed.

You are bound to make mistakes with all those links.
In fact you already made mistakes (so check all your links, some are wrong).
and this is only with three versions; imagine if you have a whole bunch to keep track of.

;)
RE: RE: Interface Writer | [release] 1.2 by SmokingCookie on 06-28-2009 at 07:13 AM

quote:
Originally posted by whiz

Ok, let's see.

js code:
var ControlsXPath = "//Interfaces/Window[@Id=\"" + WindowId + "\"]/Controls/Control";
var ElementsXPath = "//Interfaces/Window[@Id=\"" + WindowId + "\"]/Elements/Element";
/
ret.Interface[WindowId] = new Object();
ret.Interface[WindowId].Controls = new Object();
ret.Interface[WindowId].Elements = new Object();
1) Am I able to create my own, like this?  For example, to get the window title:
js code:
var CaptionsXPath = "//Interfaces/Window[@Id=\"" + WindowId + "\"]/Attributes/Caption";
var TitlesXPath = "//Interfaces/Window[@Id=\"" + WindowId + "\"]/TitleBar/Title/Text";
But...  it can't be enumerated:
js code:
var K = new Enumerator(xml.selectNodes(CaptionsXPath));
It's different, because the value isn't "<Item Parameter="Value">", but "<Item>Value</Item>".  How can I get that?

js code:
var K = new Enumerator(xml.selectNodes(ControlsXPath));
if(K.count() > 0) {
    for(; !K.atEnd(); K.moveNext()) {
        var ControlNode = K.item();
        var ControlId = ControlNode.getAttribute("Id");
        // Define an object for this control type (as in ButtonControl or StaticControl) that contains the actual control
        // Only done when necessary
        if(ControlId in ret.Interface[WindowId].Controls) {
            //[alert the user that there's 2 or more controls with the same ID]
            continue;
        }
        // You'll have to do your own stuff here
        ret.Interface[WindowId].Controls[ControlId] = "null" //[JScript control definition stuff]
    }
}
2a) If that gets a control ID, then I assume that getting the type uses the same method, replacing ".getAttribute("Id")" with ".getAttribute("xsi:type")", right?
2b) Would this work:
[code left out]

1) yes.
2) also yes, but instead of "ControlLeft" and "ControlId" variables, you may wanna use an object with these properties:

code:
var Control = new Object();
Control.Id = xmlNode.getAttribute("Id"); // xmlNode in this case is K.item();
Control.Type = xmlNode.getAttribute("xsi:type");
Control.Position = {
    "Left"    : xmlPosNode.getAttribute("Left"),
    "Top"    : xmlPosNode.getAttribute("Top"),
    "Width"    : xmlPosNode.getAttribute("Width"),
    "Height"    : xmlPosNode.getAttribute("Height") // Note that there's no comma on this one
}// Object definition, version 2

About the enumeration thingy: there's probably only one node, so enumeration would be useless with "var CaptionsXPath = "//Interfaces/Window[@Id=\"" + WindowId + "\"]/Caption";" and such. You can retrieve the caption using the following code:

JScript code:
var CaptionXPath = "//Interfaces/Window[@Id=\"" + WindowId + "\"]/Caption"
var node = xml.selectSingleNode(CaptionXPath);
var sCaption = node.text;

quote:
Originally posted by whiz
I apologise for so many questions, but this is a confusing topic for me...  :S

Never mind, I started with the same amount of questions :P

Oh and sorry for the late answer. Had no PC for over a week :S
RE: Interface Writer | [release] 1.5 by whiz on 06-28-2009 at 09:30 AM

quote:
Originally posted by CookieRevised
ok, but it is way better to edit your first post and instead replace the old script with the new(est) version.
After that you can remove all the other attachments in your other posts, they aren't needed and people will still be able to download the wrong version.
(remember, not everybody reads an entire thread to know which version is which; mostly, if they see an attachment in a post (after they came directly to that post because they were referred to it fro manother thread), they probably think it is the latest version)...
Ok, done it.  :D



quote:
Originally posted by SmokingCookie
1) yes.
2) also yes, but instead of "ControlLeft" and "ControlId" variables, you may wanna use an object with these properties:

code:
var Control = new Object();
Control.Id = xmlNode.getAttribute("Id"); // xmlNode in this case is K.item();
Control.Type = xmlNode.getAttribute("xsi:type");
Control.Position = {
    "Left"    : xmlPosNode.getAttribute("Left"),
    "Top"    : xmlPosNode.getAttribute("Top"),
    "Width"    : xmlPosNode.getAttribute("Width"),
    "Height"    : xmlPosNode.getAttribute("Height") // Note that there's no comma on this one
}// Object definition, version 2

Hang on, if "xmlNode" is "K.item()", then what's "xmlPosNode"?

quote:
Originally posted by SmokingCookie
About the enumeration thingy: there's probably only one node, so enumeration would be useless with "var CaptionsXPath = "//Interfaces/Window[@Id=\"" + WindowId + "\"]/Caption";" and such. You can retrieve the caption using the following code:

JScript code:
var CaptionXPath = "//Interfaces/Window[@Id=\"" + WindowId + "\"]/Caption"
var node = xml.selectSingleNode(CaptionXPath);
var sCaption = node.text;

1) You can use ".getAttribute()" to get a value from an "<element type="value"/>" tag, and ".selectSingleNode()" + "[node].text" to get a value from an "<element>value</element>" tag.  Is this right?
2) Can I use ".selectSingleNode()" and "[node].text" to get any text in XML written as "<element>value</element>"?
RE: Interface Writer | [release] 1.5 by SmokingCookie on 06-28-2009 at 03:24 PM

xmlPosNode is xml.selectSingleNode("//Interfaces/Window[@Id=\"" + WindowId + "\"]/Controls/Control[@Id=\"" + ControlId + "\"]/Position");



1) Yes
2) yes (isn't that the same question as 1? :P )
RE: Interface Writer | [release] 1.5 by whiz on 06-29-2009 at 06:31 PM

Right, I think I might actually understand it now...  I will keep working at it!

EDIT: Um...  I need more help.  :S

code:
Message in Script Debugger
XML document must have a top level element.
 at 0 (0)
What does that mean?  There's nothing wrong with the file...
RE: Interface Writer | [release] 1.5 by SmokingCookie on 06-29-2009 at 07:12 PM

That's what the forums are for ;)


RE: Interface Writer | [release] 1.5 by mynetx on 06-30-2009 at 07:31 AM

quote:
Originally posted by whiz
What does that mean? 
Usually that refers to a missing root node, like <html> in HTML.
RE: Interface Writer | [release] 2.0 | 07/11/2009 by whiz on 11-07-2009 at 01:49 PM

Version 2.0 has been released!  :D  And now it loads files!  :D:D:D

Leave any comments or suggestions here!  ;)


RE: Interface Writer | [release] 2.0 | 07/11/2009 by mynetx on 11-07-2009 at 02:04 PM

Whiz,

Great job you’ve done.  I have downloaded Interface Writer 2.0 and here are my suggestions on what you can make better :)  There is no particular order in my list.

  • Use a system dialog for opening and saving files. This allows easy selection of files without having to know their names.  You can find more information about Common Dialogs at MSDN.
    jscript code:

  • Remove the help tooltip from the ListView listing all Controls/elements. The tooltip is needed for hovering ellipsed items in the grid.
  • Add support for Interface Tester to see the changes without having to create a test script.
  • Add support for custom attributes.
  • Add options dialog for various options, like "auto-save when I change a field" or "auto-create backup on opening a file" or "change indention style on generated XMLs".
  • Add a list of recently used files.
  • Add texts to the bottombar buttons. Always hovering them to guess their meaning is a bit strange.

So far for this list.  Don’t forget—what you’ve already done is amazing, just keep up the good work.

Best,
mynetx
RE: Interface Writer | [release] 2.0 | 07/11/2009 by whiz on 11-07-2009 at 02:32 PM

quote:
Originally posted by mynetx
  • Use a system dialog for opening and saving files. This allows easy selection of files without having to know their names.  You can find more information about Common Dialogs at MSDN.
    jscript code:
    cd = new ActiveXObject("MSComDlg.CommonDialog"); // create the object
    cd.Filter = "All Files(*.*)|*.*|JScript Files(*.js)|*.js"; // set file filter
    cd.FilterIndex = 2;
    cd.MaxFileSize = 128; // must set MaxFileSize. otherwise you will get an error
    cd.ShowOpen(); // show it to user
    file = cd.FileName; // retrieve file + path
    if (!file) { // If the user does enter file exit
        MsgPlus.DisplayToast("", "You must enter a file name");
    }
    else {
        MsgPlus.DisplayToast("", "The user selected:\n" + file );
    }

I've just tested that, but it doesn't seem to work on initialization:
code:
From the Script Debugger
Script is starting
Error: unknown (code: -2147221230)
       File: FnInitialization.js. Line: 1.
Script has failed to start
Something wrong with the ActiveX object?



quote:
Originally posted by mynetx
  • Remove the help tooltip from the ListView listing all Controls/elements. The tooltip is needed for hovering ellipsed items in the grid.

Removed.  But what do you mean by "ellipsed items"?  Do you mean a tooltip for each window/control/element with extra details?



quote:
Originally posted by mynetx
  • Add support for Interface Tester to see the changes without having to create a test script.

Had just been thinking about that, but at the moment, I've done it so that the interface is saved as a temporary file, and then opened using MsgPlus::CreateWnd.



quote:
Originally posted by mynetx
  • Add support for custom attributes.

I'll work on this, but it would take a while to specify what attributes go with what in a list, so I'll probably let the user pick what attributes they want to use with a text area or something.



quote:
Originally posted by mynetx
  • Add options dialog for various options, like "auto-save when I change a field" or "auto-create backup on opening a file" or "change indention style on generated XMLs".
  • Add a list of recently used files.

They'll both need the registry functions, but I'll add them.  Eventually.



quote:
Originally posted by mynetx
  • Add texts to the bottombar buttons. Always hovering them to guess their meaning is a bit strange.

Fair enough.  ;)  Will do.
RE: RE: Interface Writer | [release] 2.0 | 07/11/2009 by CookieRevised on 11-07-2009 at 05:43 PM

quote:
Originally posted by whiz
quote:
Originally posted by mynetx
Use a system dialog for opening and saving files. This allows easy selection of files without having to know their names.  You can find more information about Common Dialogs at MSDN.
jscript code:
cd = new ActiveXObject("MSComDlg.CommonDialog"); // create the object
cd.Filter = "All Files(*.*)|*.*|JScript Files(*.js)|*.js"; // set file filter
cd.FilterIndex = 2;
cd.MaxFileSize = 128; // must set MaxFileSize. otherwise you will get an error
cd.ShowOpen(); // show it to user
file = cd.FileName; // retrieve file + path
if (!file) { // If the user does enter file exit
    MsgPlus.DisplayToast("", "You must enter a file name");
}
else {
    MsgPlus.DisplayToast("", "The user selected:\n" + file );
}

I've just tested that, but it doesn't seem to work on initialization:
code:
From the Script Debugger
Script is starting
Error: unknown (code: -2147221230)
       File: FnInitialization.js. Line: 1.
Script has failed to start
Something wrong with the ActiveX object?
Yes, you do not have the proper design license.
I strongly suggest not to use that ActiveX, but instead use the proper Windows API.
See: CookieRevised's reply to UserAccounts.CommonDialog alternative for Vista

and "cd = " should be "var cd ="

Also (@mynetx):
quote:
cd.MaxFileSize = 128; // must set MaxFileSize. otherwise you will get an error
128 is waaaaaaaay to low. The MaxFileSize is the maximum path length, this should at least be 260, like it is defined in Windows (=MAXPATH). So, a value like 2048 should be given on current systems.





quote:
Originally posted by whiz
quote:
Originally posted by mynetx
  • Remove the help tooltip from the ListView listing all Controls/elements. The tooltip is needed for hovering ellipsed items in the grid.

Removed.  But what do you mean by "ellipsed items"?  Do you mean a tooltip for each window/control/element with extra details?
Ellipsed items are items which are too long to be displayed on one line. As such, the are cropped and "..." (an ellipsis) is added to the end. With default Windows behaviour, when you hover over such items a tooltip will pop up showing the complete line.

However, that does not mean you should not display a tooltip when items do fit in the available space. Common practice is to always show a tooltip when hovering over items (too long or not), when at least one item is too long to be displayed.



;)
RE: Interface Writer | [release] 2.0 | 07/11/2009 by mynetx on 11-07-2009 at 06:28 PM

quote:
Originally posted by whiz
Something wrong with the ActiveX object?
Here it works.  What Windows version are you using?
quote:
Originally posted by whiz
what do you mean by "ellipsed items"?
Look.  The red items have tooltips automatically as they don’t show completely. My suggestion: Give the window a larger default size. (Good that it is resizable!)

[Image: 2ujnqfd.jpg]

And, why does
xml code:
<Position ClientWidth="210" ClientHeight="224" InitialPos="CenteredScreen"/>
not show up as Size in the Window properties dialog?
RE: RE: Interface Writer | [release] 2.0 | 07/11/2009 by CookieRevised on 11-07-2009 at 11:07 PM

quote:
Originally posted by mynetx
quote:
Originally posted by whiz
Something wrong with the ActiveX object?
Here it works.  What Windows version are you using?
Windows version doesn't matter, see my previous post.

;)
RE: Interface Writer | [release] 2.0 | 07/11/2009 by whiz on 11-08-2009 at 11:57 AM

quote:
Originally posted by CookieRevised
I strongly suggest not to use that ActiveX, but instead use the proper Windows API.
See: CookieRevised's reply to UserAccounts.CommonDialog alternative for Vista
Done.

quote:
Originally posted by CookieRevised
Ellipsed items are items which are too long to be displayed on one line. As such, the are cropped and "..." (an ellipsis) is added to the end. With default Windows behaviour, when you hover over such items a tooltip will pop up showing the complete line.

However, that does not mean you should not display a tooltip when items do fit in the available space. Common practice is to always show a tooltip when hovering over items (too long or not), when at least one item is too long to be displayed.
So... how do I add a tooltip for each item?
RE: Interface Writer | [release] 2.0 | 07/11/2009 by CookieRevised on 11-08-2009 at 05:56 PM

Try to avoid tooltips to begin with.. aka make the list columns wider.


RE: Interface Writer | [release] 2.0 | 07/11/2009 by whiz on 11-09-2009 at 06:52 PM

quote:
Originally posted by CookieRevised
Try to avoid tooltips to begin with.. aka make the list columns wider.
That's what I'm doing at the moment...  except I've added a few extra columns for some new features, so it's quite a long window now...  :P
RE: Interface Writer | [release] 2.0 | 07/11/2009 by CookieRevised on 11-10-2009 at 07:45 AM

Cool, then you could also make the window a bit taller too, to compensate the widthness/wideness/whatever-ness :p. But remember that netbooks get popular these days, they have a small resolution, so stay well below 1024x600 ;) (1024 because of 1024x768 screens, and 600 because of 1080x600 screens)


RE: Interface Writer | [release] 2.0 | 07/11/2009 by whiz on 11-10-2009 at 04:14 PM

quote:
Originally posted by CookieRevised
Cool, then you could also make the window a bit taller too, to compensate the widthness/wideness/whatever-ness :p. But remember that netbooks get popular these days, they have a small resolution, so stay well below 1024x600 ;) (1024 because of 1024x768 screens, and 600 because of 1080x600 screens)
The window's now about 600x400., but I've left the minimum sizes, so it can be smaller if the user wants it to be.  I've also decided just to show the basic information in the main window now.  :P

And if anyone's interested, the new version will support window templates (DialogTmpl, WindowTmpl and ChildTmpl), window initial positions and custom attributes.  :D
RE: Interface Writer | [release] 2.2 | 29/11/2009 by whiz on 11-29-2009 at 05:19 PM

Version 2.2 is out!  Enjoy the new features and updated window style!  :D


RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 01-30-2010 at 01:16 PM

Introducing version 2.5!  :P

Now with a recently used file list, window builder and interface viewer, as well as some other useful updates...  enjoy!


RE: Interface Writer | [release] 2.5 | 30/01/2010 by SmokingCookie on 01-30-2010 at 01:25 PM

Nice!

I have a suggestion for any future update (don't rush to the next version, just add to your to-do list if you want): rename any component (like window ID, control ID, etc.) from within the list-view. Basically like renaming a file or folder in Windows Explorer. Screenshot of what I mean:

[Image: attachment.php?pid=986437]

If you need any help on this, you know where to find me. You can also take a look at the code; see the link in my signature for the script.


RE: Interface Writer | [release] 2.5 | 30/01/2010 by MeEtc on 01-31-2010 at 02:40 AM

I'm getting an error when trying to launch this, and not able to show the menu..

code:
Script is starting
+----------------------+
| Interface Writer 2.5 |
+----------------------+
<-- Start version check. -->
--> Checking for version registry key...
--> | Current version: 2.5
--> | Unable to retrieve previous version.
--> | | Displaying first run dialog...
--> Saving version registry key...
--> | Key saved.  Value: 2.5
<-- End version check. -->
Script is now loaded and ready
Error: Invalid root in registry key "HKCU\SOFTWARE\Patchou\Messenger Plus! Live\GlobalSettings\Scripts\Interface Writer\Settings\id and email\Options\ChkDebug". (code: -2147024894)
       File: FnRegistryObj.js. Line: 19.
Function OnEvent_Initialize returned an error. Code: -2147352567
Error: Invalid root in registry key "HKCU\SOFTWARE\Patchou\Messenger Plus! Live\GlobalSettings\Scripts\Interface Writer\Settings\id and email\Recent". (code: -2147024894)
       File: FnRegistryObj.js. Line: 19.
Function OnGetScriptMenu returned an error. Code: -2147352567

RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 01-31-2010 at 08:48 AM

Oops, didn't check for it not existing...  I'll fix it later today.

Edit: I've fixed the Debug key glitch, but I can't reproduce the Recent key error.  It might be because of a previous version - try uninstalling it and reinstalling the updated version on the first post.


RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 01-31-2010 at 04:00 PM

quote:
Originally posted by SmokingCookie
I have a suggestion for any future update (don't rush to the next version, just add to your to-do list if you want): rename any component (like window ID, control ID, etc.) from within the list-view. Basically like renaming a file or folder in Windows Explorer. Screenshot of what I mean:

(image)

If you need any help on this, you know where to find me. You can also take a look at the code; see the link in my signature for the script.

Well, I'm guessing it's something to do with this...
js code:
if(Cache.Languages["Array"][Cache["LanguageSelection"]] === "English.xml") return ScriptLanguage.DisplayAlert(PlusWnd.Handle,"AlertEnglishRequired");
Interop.Call("User32.dll","SendMessageW",PlusWnd.GetControlHandle("vLstLanguages"),LVM_EDITLABELW,
Cache["LanguageSelection"],0);
for(var i in Cache[PlusWnd.WindowId].Hotkeys) Cache[PlusWnd.WindowId].Hotkeys[i].Unregister();
But I would have no idea how to implement it...  :S
RE: Interface Writer | [release] 2.5 | 30/01/2010 by SmokingCookie on 01-31-2010 at 05:04 PM

Well, I think this is the easy part:

JScript code:
Interop.Call("User32.dll","SendMessageW",PlusWnd.GetControlHandle("MyListView"),LVM_EDITLABELW,ItemToRename,0);

You should then listen for WM_NOTIFY ( = 0x004E) notifications. That's where the tricky part comes in: Along with WM_NOTIFY, an NMHDR structure is passed, which can be moved to a known location by RtlMoveMemory (see MSDN). Reading the data at position 8, you should find LVN_ENDLABELEDITW ( = LVN_FIRST - 76; LVN_FIRST = 0 - 100). You must retrieve the edit control's handle through LVM_GETEDITCONTROL ( = LVM_FIRST + 24; LVM_FIRST = 0x1000). Once you know the handle to the edit control, you can retrieve its text length and text itself with WM_GETTEXTLENGTH ( = 0x000E) and WM_GETTEXT ( = 0x000D), respectively.

Oh and the ListViewControl's AllowEdit attribute should be true in your interface XML
RE: Interface Writer | [release] 2.5 | 30/01/2010 by MeEtc on 02-01-2010 at 12:01 AM

I didn't have a previous version before now. I'll try the update when I get home.


RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 02-02-2010 at 06:34 PM

quote:
Originally posted by SmokingCookie
Well, I think this is the easy part:

JScript code:
Interop.Call("User32.dll", "SendMessageW", PlusWnd.GetControlHandle("MyListView"), LVM_EDITLABELW, ItemToRename, 0);

I've put this in the "Rename" option's event:
js code:
Interop.Call("User32.dll", "SendMessageW", WndWriterManageWindows.GetControlHandle("LstWindows"), 18, Writer.WndSel[0], 0);
But then what?  Nothing happens...

quote:
Originally posted by SmokingCookie
You should then listen for WM_NOTIFY ( = 0x004E) notifications. That's where the tricky part comes in: Along with WM_NOTIFY, an NMHDR structure is passed, which can be moved to a known location by RtlMoveMemory (see MSDN). Reading the data at position 8, you should find LVN_ENDLABELEDITW ( = LVN_FIRST - 76; LVN_FIRST = 0 - 100). You must retrieve the edit control's handle through LVM_GETEDITCONTROL ( = LVM_FIRST + 24; LVM_FIRST = 0x1000). Once you know the handle to the edit control, you can retrieve its text length and text itself with WM_GETTEXTLENGTH ( = 0x000E) and WM_GETTEXT ( = 0x000D), respectively.
Not sure how to do this...  :S  I've registered the event:
js code:
WndWriterManageWindows.RegisterMessageNotification(78);
But there are messages appearing for all sorts!

quote:
Originally posted by SmokingCookie
Oh and the ListViewControl's AllowEdit attribute should be true in your interface XML
Done that.
RE: Interface Writer | [release] 2.5 | 30/01/2010 by SmokingCookie on 02-10-2010 at 07:32 PM

Kinda forgot that you'd replied, I'm sorry!

When you receive the WM_NOTIFY message, the lParam is important: it contains an NMHDR structure. You can access this structure using RtlMoveMemory() in Kernel32.dll as follows:

JScript code:
var NMHDR = Interop.Allocate(52);

Interop.Call("Kernel32.dll","RtlMoveMemory",NMHDR.DataPtr,lParam,52);

Reading byte 8 from the NMHDR structure, you should be able to filter the LVN_ENDLABELEDITW value. You should then perform the actions I described above.
RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 02-11-2010 at 08:03 PM

Ok, I've managed to make the rename box appear (since it wasn't working, I checked the Schema Documentation - it was "AllowEditText").  :P  I've currently got this:

js code:
function OnWndWriterManageWindowsEvent_MessageNotification(objWnd, Message, wParam, lParam)
{
    if (Message === 78) // WM_NOTIFY
    {
        var NMHDR = Interop.Allocate(52);
        Interop.Call("kernel32", "RtlMoveMemory", NMHDR.DataPtr, lParam, 52);
        if (NMHDR.ReadString(8) === -176) // LVN_ENDLABELEDITW
        {
            Debug.Trace("Renamed!");
        }
    }
}
But I'm assuming that the NMHDR structure doesn't actually return the actual number at position 8...  how should I do it?
RE: Interface Writer | [release] 2.5 | 30/01/2010 by SmokingCookie on 02-12-2010 at 08:34 AM

You shouldn't use NMHDR.readSTRING(8), but NMHDR.readDWORD(8)

Besides, you can always check the value read from a position in a DataBloc object:

JScript code:
var Byte1 = DataBloc.readDWORD(0);
var Bute2 = DataBloc.readSTRING(0);

Debug.Trace(Byte1);
Debug.Trace(Byte2);

Then check if the output is what you expect.
RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 02-12-2010 at 07:41 PM

Ok, that bit works.  I've now got:

js code:
function OnWndWriterManageWindowsEvent_MessageNotification(objWnd, Message, wParam, lParam)
{
    if (Message === 78)
    {
        var TmpNMHDR = Interop.Allocate(52);
        Interop.Call("kernel32", "RtlMoveMemory", TmpNMHDR.DataPtr, lParam, 52);
        if (TmpNMHDR.ReadDWORD(8) === -176)
        {
            var TmpEditHandle = WndWriterManageWindows.SendControlMessage("LstWindows", 4120, 0, 0);
            var TmpEditLength = WndWriterManageWindows.SendControlMessage("LstWindows", 13, 0, 0);
            var TmpEditText = Interop.Allocate(TmpEditLength);
            var TmpEditCopied = WndWriterManageWindows.SendControlMessage("LstWindows", 14, TmpEditLength, TmpEditText.DataPtr);
            AlertDialog("Message: " + Message + "\nNMHDR: " + TmpNMHDR.ReadDWORD(8) + "\n\nwParam: " + wParam + "\nlParam: " + lParam + "\n\nText: " + TmpEditText + "\nLength: " + TmpEditLength + "\nCopied: " + TmpEditCopied + "\nHandle: " + TmpEditHandle);
        }
    }
}
But the alert gives me this:
code:
Message: 78
NMHDR: -176

wParam: 8133
lParam: 457340

Text:
Length: 0
Copied: 0
Handle: 984598

The text value returns "" (an empty string).  :S
RE: Interface Writer | [release] 2.5 | 30/01/2010 by SmokingCookie on 02-13-2010 at 08:49 AM

That's weird..

Could you try:

JScript code:
var length = (Interop.Call("User32.dll","SendMessageW",Edit,WM_GETTEXTLENGTH,0,0) + 1);
var Buffer = Interop.Allocate((length + 1) * 2);
var lResult = Interop.Call("User32.dll","SendMessageW",Edit,WM_GETTEXT,length,Buffer.DataPtr);
// MessageBox is a class in my script; use your AlertDialog instead
//MessageBox.Show("Copied\t: " + lResult + "\nLength\t: " + length);

Works for me.

Nb: the length variable contains (GetTextLengthResult + 1)!
RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 02-14-2010 at 10:50 AM

quote:
Originally posted by SmokingCookie
That's weird..

Could you try:

JScript code:
var length = (Interop.Call("User32.dll","SendMessageW",Edit,WM_GETTEXTLENGTH,0,0) + 1);
var Buffer = Interop.Allocate((length + 1) * 2);
var lResult = Interop.Call("User32.dll","SendMessageW",Edit,WM_GETTEXT,length,Buffer.DataPtr);
// MessageBox is a class in my script; use your AlertDialog instead
//MessageBox.Show("Copied\t: " + lResult + "\nLength\t: " + length);

Works for me.

Nb: the length variable contains (GetTextLengthResult + 1)!
Didn't work at first - said "Edit" was undefined.  I assumed that was the handle of the ListViewControl - WndWriterManageWindows.SendControlMessage("LstWindows", 4120, 0, 0); - but I end up with the following message:
code:
Copied    : 11
Length    : 1
The "Copied" value is actually the length, and "Length" always returns "1" (a number, not a string - a boolean, maybe?).  Any more ideas?
RE: Interface Writer | [release] 2.5 | 30/01/2010 by SmokingCookie on 02-14-2010 at 11:01 AM

quote:
Originally posted by MSDN
Return Value

    The return value is the length of the text in TCHARs, not including the terminating null character.

(see http://msdn.microsoft.com/en-us/library/ms632628%28VS.85%29.aspx)

It should return the visible length (that is, text you can read)... *-)

But you more or less have it working now: Buffer.readSTRING(0); should return the new filename/control ID or whatever you want to rename this way.

Oh and don't forget to collect garbage: always destroy DataBloc objects (if possible), by setting its size to zero:

JScript code:
var Buffer = Interop.Allocate(123);

Buffer.Size = 0;

There are just a few situations in which you cannot destroy memory blocks instantly, but I don't think you'll be in any of those.
RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 02-14-2010 at 11:22 AM

js code:
AlertDialog("Copied\t: " + lResult + "\nLength\t: " + length + "\n\nValue\t: " + Buffer.readSTRING(0) + " (" + Buffer.readSTRING(0).length + ")");
code:
Copied    : 11
Length    : 1

Value    :  (0)
:S
RE: Interface Writer | [release] 2.5 | 30/01/2010 by SmokingCookie on 02-14-2010 at 12:53 PM

Could you post the entire OnWindowIdEvent_MessageNotification(...); function?


RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 02-14-2010 at 01:41 PM

Actually, don't worry.  I've worked it out: I had WM_GETTEXT and WM_GETTEXTLENGTH the wrong way round...  :P

Just one last question: how can I trigger the rename box to appear, other than clicking on the entry in the ListViewControl (for example, through a right-click menu or button)?


RE: Interface Writer | [release] 2.5 | 30/01/2010 by SmokingCookie on 02-14-2010 at 01:44 PM

Yeah, that makes a whole lot of difference :P

The menu thingy is gonna be very complex. If you want an example, look at my code again. Search for "OnWndSettings_LanguageEvent_LstViewRClicked" in the same file you found the message notification event. If there's anything you need explained, I'm here.

As for the button: that'll be easier:

JScript code:
function OnWindowIdEvent_CtrlClicked(PlusWnd,ControlId) {
    if(ControlId === "BtnRename") {
        Interop.Call("User32.dll",
        "SendMessageW",
        PlusWnd.GetControlHandle("MyListView"),
        LVM_EDITLABELW,ItemToRename,0);
    }
}

You can get the ItemToRename value by declaring a global variable and assigning it in each list-view event. Be sure to assign it -1 when the window is destroyed.
RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 02-14-2010 at 02:00 PM

quote:
Originally posted by file "Video Converter Plus! \ WndSettings_Language.js"
To stop the page extending, I've hidden the code in this post.  :)
Spoiler:
js code:
if(Cache.Languages["Array"][Cache["LanguageSelection"]] === "English.xml") return ScriptLanguage.DisplayAlert(PlusWnd.Handle,"AlertEnglishRequired");
>>>Interop.Call("User32.dll","SendMessageW",PlusWnd.GetControlHandle("vLstLanguages"),LVM_EDITLABELW,Cache["LanguageSelection"],0);<<<
for(var i in Cache[PlusWnd.WindowId].Hotkeys) Cache[PlusWnd.WindowId].Hotkeys[i].Unregister();
break;

js code:
Interop.Call("User32.dll", "SendMessageW", WndWriterManageWindows.GetControlHandle("LstWindows"), 4214, Writer.WndSel[0], 0);
It works!  :P  Thanks for all your help!

Edit: check your reputation...  ;)
RE: Interface Writer | [release] 2.5 | 30/01/2010 by SmokingCookie on 02-14-2010 at 02:04 PM

You're welcome :)

Oh, and in what windows will you be implementing this?


RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 02-14-2010 at 02:12 PM

quote:
Originally posted by SmokingCookie
You're welcome :)

Oh, and in what windows will you be implementing this?
I'll probably use it with the window, control and element managers (all the ones with a ListViewControl).  :D
RE: Interface Writer | [release] 2.5 | 30/01/2010 by CookieRevised on 02-14-2010 at 04:32 PM

PS:

quote:
Originally posted by whiz
quote:
Originally posted by SmokingCookie
That's weird..

Could you try:
JScript code:
var length = (Interop.Call("User32.dll","SendMessageW",Edit,WM_GETTEXTLENGTH,0,0) + 1);
var Buffer = Interop.Allocate((length + 1) * 2);
var lResult = Interop.Call("User32.dll","SendMessageW",Edit,WM_GETTEXT,length,Buffer.DataPtr);
// MessageBox is a class in my script; use your AlertDialog instead
//MessageBox.Show("Copied\t: " + lResult + "\nLength\t: " + length);



var Buffer = Interop.Allocate((length + 1) * 2);
should be
var Buffer = Interop.Allocate(length * 2);
since you already increased length by one (to accomodate the null character).

As for the garbage collection, that is a very good practice indeed, but it isn't needed for scripting as Plus! already does the garbage collection for you.
Aka, code will run 'faster' if Plus! does it internally, compared to the need to parse, execute and handle yet another script line.


* CookieRevised slaps whiz around for swapping WM_GETTEXTLENGTH and WM_GETTEXT
... frustrating stuff I can imagine


;)
RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 02-14-2010 at 06:32 PM

quote:
Originally posted by CookieRevised
var Buffer = Interop.Allocate((length + 1) * 2);
should be
var Buffer = Interop.Allocate(length * 2);
since you already increased length by one (to accomodate the null character).
Fair enough, I'll sort that.

quote:
Originally posted by CookieRevised
As for the garbage collection, that is a very good practice indeed, but it isn't needed for scripting as Plus! already does the garbage collection for you.
Aka, code will run 'faster' if Plus! does it internally, compared to the need to parse, execute and handle yet another script line.
Yep, I'll take that out.  :)

quote:
Originally posted by CookieRevised

* CookieRevised slaps whiz around for swapping WM_GETTEXTLENGTH and WM_GETTEXT

... frustrating stuff I can imagine


;)
Yes, it happens.  ;)
RE: RE: Interface Writer | [release] 2.5 | 30/01/2010 by SmokingCookie on 02-14-2010 at 08:09 PM

quote:
Originally posted by CookieRevised
[...]
should be
[...]
since you already increased length by one (to accomodate the null character).

Stupid :wall: :P
RE: Interface Writer | [release] 2.5 | 30/01/2010 by whiz on 02-16-2010 at 02:57 PM

And...  version 2.7 is out!  Only a few updates, so I'm not bothering to update the screenshot.  Enjoy!  :P

Ready to download it?  Click here to start the download...


RE: Interface Writer | [release] 2.7 | 16/02/2010 by billyy on 02-16-2010 at 04:20 PM

Wow lovely O_O
aaaand it crashes msn O_O


RE: Interface Writer | [release] 2.7 | 16/02/2010 by whiz on 02-16-2010 at 04:58 PM

quote:
Originally posted by billyy
Wow lovely O_O
aaaand it crashes msn O_O
Does it?  What were you trying to do?
RE: Interface Writer | [release] 2.7 | 16/02/2010 by billyy on 02-16-2010 at 05:55 PM

well it just crashed as soon as i installed it.. but now works fine..
doesnt have to be something about the script :/

Works awesome, but it would be even better if you could just set the left offset for a group of controls.


RE: Interface Writer | [release] 2.7 | 16/02/2010 by whiz on 02-17-2010 at 08:13 PM

quote:
Originally posted by billyy
Works awesome, but it would be even better if you could just set the left offset for a group of controls.
That's not a bad idea...  it could even be so that you can select any or all of the items in a grid, and set one or more values to them all.  I'll have a think about it...  :)
RE: Interface Writer | [release] 2.7 | 16/02/2010 by billyy on 02-17-2010 at 08:23 PM

sweet :)


RE: Interface Writer | [release] 2.7 | 16/02/2010 by whiz on 02-18-2010 at 08:57 AM

If anyone has any other ideas, feel free to post them and I'll make a to-do list on the main post.  ;)


RE: Interface Writer | [release] 2.7 | 16/02/2010 by billyy on 02-18-2010 at 08:03 PM

Erm i have noticed that if i make like a load of controls and than edit the window it removes all controls (function or glitch i don't know) but it rly bummed me out it didn't even warn me :(


RE: Interface Writer | [release] 2.7 | 16/02/2010 by whiz on 02-18-2010 at 08:18 PM

quote:
Originally posted by billyy
Erm i have noticed that if i make like a load of controls and than edit the window it removes all controls (function or glitch i don't know) but it rly bummed me out it didn't even warn me :(
Hmm...  you've got a point there.  It's made in the way that rather than changing an ID, it creates a new window with the new ID, copies the attributes (but not controls), and then deletes the old one.  I'll have to change that...

I never even thought of that.  :P
RE: Interface Writer | [release] 2.7 | 16/02/2010 by billyy on 02-18-2010 at 08:21 PM

Well its a complicated program i gues you cant have evrything right the first time :P
But i realy like it, it has helped out a lot. Probably in the 5% most usefull scripts for msg plus :|


RE: Interface Writer | [release] 2.7 | 16/02/2010 by whiz on 02-20-2010 at 11:27 AM

It's good to hear.  ;)  Hopefully I'll have these problems fixed in the next version.  :D


Interface Writer | [beta] 2.8 | 21/02/2010 by whiz on 02-21-2010 at 05:28 PM

Please note that this is a beta version!  If you find any errors, please post details here...



Features
  • basically, it writes windows for you :P
  • can be saved as an XML file, or a copy/paste compatible source code
  • load existing interfaces and edit them
  • import, save as and save copies to different files
  • unlimited windows, controls and elements
  • graphically build windows with the simple builder tool
  • view interface files without needing the editor
  • user-friendly - just double-click to add or edit windows or controls
  • full validation of file paths, window IDs and control IDs

New in this Version
  • added: multiple window tasks - edit and delete multiple windows
  • fixed: window editing - editing a window no longer deletes any controls or elements included
  • changed: debugging - new event messages and debug output to log file
  • changed: window styles - some button and drop-down menu styles changed :)

Screenshot (click to enlarge)
[Image: interfacewriter.png]
Note that this is an old screenshot, and it doesn't reflect some newer features.

To-do List
  • set one or more values to multiple items in the control/element grids
  • add more preset windows, and allow the user to create their own

RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by billyy on 02-21-2010 at 06:20 PM

I have no idea why and i think it fluked but one time i selected a window and than deselected it and it just disapeared...
But it seems to work well so far. Thanks i love it :)


RE: Interface Writer | [beta] 2.8 | 21/02/2010 by whiz on 02-21-2010 at 06:38 PM

quote:
Originally posted by billyy
I have no idea why and i think it fluked but one time i selected a window and than deselected it and it just disapeared...
But it seems to work well so far. Thanks i love it :)
Well, if it happens again, see if there's any similarity, and also check the debugger for clues in there (enable the debug option first).
RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by SmokingCookie on 02-23-2010 at 10:58 AM

I have a two suggestions:

  • You might want to make the settings window a bit larger, to improve user-friendliness.
  • I see the benefit of the Help guide mode, but I think it looks a lot more professional to make a little help button in the title bar ;)

Don't rush to an update though; these suggestions are only to change the visual appearance of the script and not to fix any bugs ;)
RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by whiz on 02-23-2010 at 04:05 PM

quote:
Originally posted by SmokingCookie
  • You might want to make the settings window a bit larger, to improve user-friendliness.

Could do, and perhaps I'll split it into categories with figure elements and legend keys.  :)  I'm thinking of adding more options as well anyway.

quote:
Originally posted by SmokingCookie
  • I see the benefit of the Help guide mode, but I think it looks a lot more professional to make a little help button in the title bar ;)

You mean like you've done in your Video Converter Plus! script?  :D
RE: RE: Interface Writer | [beta] 2.8 | 21/02/2010 by billyy on 02-23-2010 at 04:14 PM

quote:
Originally posted by whiz

Well, if it happens again, see if there's any similarity, and also check the debugger for clues in there (enable the debug option first).
ofcourse whiz :)
RE: RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by SmokingCookie on 02-23-2010 at 05:02 PM

quote:
Originally posted by whiz

[...]
Could do, and perhaps I'll split it into categories with figure elements and legend keys.  :)  I'm thinking of adding more options as well anyway.

Legend keys? What exactly do you mean by that?

quote:
Originally posted by whiz

[...]
You mean like you've done in your Video Converter Plus! script?  :D

You've got it :P
RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by whiz on 02-24-2010 at 06:51 PM

quote:
Originally posted by SmokingCookie
quote:
Originally posted by whiz
Could do, and perhaps I'll split it into categories with figure elements and legend keys.  :)  I'm thinking of adding more options as well anyway.
Legend keys? What exactly do you mean by that?
Umm...  like the headings of a section.  Like you get in Windows.  I don't know what you're supposed to call them.  ;)

Here's an example.  Like where it says "Tasks", "Browse Folders", and so on.

[Image: setup-studio-windows-xp-configuration-fo...ptions.gif]
RE: RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by SmokingCookie on 02-24-2010 at 06:57 PM

quote:
Originally posted by whiz
[...]
Umm...  like the headings of a section.  Like you get in Windows.  I don't know what you're supposed to call them.  ;)

Here's an example.  Like where it says "Tasks", "Browse Folders", and so on.

[image]

Well, I usually call them groups.

Little offtopic, but ehh; do you write your own interfaces using this script? :P
RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by whiz on 02-24-2010 at 07:17 PM

quote:
Originally posted by SmokingCookie
Little offtopic, but ehh; do you write your own interfaces using this script? :P
Umm...  no.  :P  Come to think about it, why don't I?  :D

Probably because I do a lot of copy/paste with window/control/element interfaces, but still, I could do them with it...  ;)
RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by SmokingCookie on 02-24-2010 at 07:20 PM

There goes a brand new suggestion: making an "in-script" clipboard-like variable or object (array?) to copy and paste windows/controls etc. (I)


RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by whiz on 02-24-2010 at 07:25 PM

Ooh...  that's a great idea.  Could get kind of complicated, though.

Could do it so you can copy a window/control/element, but if you paste it where there's already one with the same name (with windows, or controls/elements in the same window), it would have to prompt for a new name or something.  :)


RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by SmokingCookie on 02-24-2010 at 07:30 PM

Complicated indeed, but if you get this done, you'll get at least an enormous ego-boost :P

About the control/element ID or name thingy, you'll have to loop through the existing items.

For the window IDs, you'll have to prompt immediately if the window is pasted in the same file..


RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by billyy on 02-26-2010 at 11:21 PM

I was making a text box 500x20 and whne i checked out the code there was none O_o
As well as i am wondering how to add a text above the box trough interface writer, would that be caption? Becuz that don't work O_o

edit:
HUH!
While typing that it hapened again, my window is gone xD
Urgh now i don't at all know how *facepalm*


RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by whiz on 02-28-2010 at 10:15 AM

quote:
Originally posted by billyy
I was making a text box 500x20 and whne i checked out the code there was none O_o
Er...  I have no idea why.  Does the control appear if you preview the window?

quote:
Originally posted by billyy
As well as i am wondering how to add a text above the box trough interface writer, would that be caption? Becuz that don't work O_o
Captions are only supported by text, checkbox, radio, button and menu button controls.  You would need an additional control for that.

quote:
Originally posted by billyy
edit:
HUH!
While typing that it hapened again, my window is gone xD
Urgh now i don't at all know how *facepalm*
:S  Is there any errors in the script debug?
RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by billyy on 02-28-2010 at 01:05 PM

No the code button won't work for anything!
And theres nothing when the window gets removed :(

Another thing, when i create a new file and close it without doing anything i can't reopen it. It doesn't matter because the window is empty but would be cool if it wrote something in the xml file so i COULD open it :/

Lol sorry theres so much but it would be cool if it was perfect, alltough nothing is :P


RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by whiz on 02-28-2010 at 01:37 PM

quote:
Originally posted by billyy
No the code button won't work for anything!
And theres nothing when the window gets removed :(
Hang on, I think you've misunderstood the purpose of the code window.  The additional code prompt is where you can add custom attributes to windows, controls or elements.  It doesn't show you the actual code for the window, control or element.  You can use it to add alignment, templates and so on.
RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by billyy on 02-28-2010 at 01:40 PM

No it works just have to wait rly rly long O_o
But when ever the window disapears i don't get a debug message or anything :/


RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by whiz on 02-28-2010 at 02:53 PM

quote:
Originally posted by billyy
No it works just have to wait rly rly long O_o
But when ever the window disapears i don't get a debug message or anything :/
:S  Can you take a screenshot of it so I can see the problem?
RE: Interface Writer | [release] 2.7 ~ [beta] 2.8 | 16/02/2010 by billyy on 02-28-2010 at 02:58 PM

Yes next time i will.


RE: Interface Writer | [beta] 2.8 | 16/02/2010 by whiz on 03-02-2010 at 03:46 PM

Ok, I've updated the to-do list, and I've added Interface Writer back into the online editor.  If anyone wants to help, PM me.  :)

Edit: also, I've managed to get a clipboard working.  It's not exactly user friendly, and it only takes one item at a time (for now), but it's a start.  :D


RE: Interface Writer | [release] 2.9 | 10/03/2010 by whiz on 03-10-2010 at 08:26 PM

Version 2.9 is out, with a clipboard!  :P  And some other miscellaneous changes - see the change log for the rest.  :)

I haven't got round to all of the stuff I want to do - you'll see there's still loads in the to-do list.  ;)  I'll get round to it eventually, but for now, I have to study for exams, so don't expect an update for a while...


RE: Interface Writer | [release] 2.9 | 10/03/2010 by SmokingCookie on 03-14-2010 at 09:42 AM

Good to hear (or read, whatever :P )

I've read your to-do list:

quote:
multiple items on the clipboard
I'm not sure of how you handle clipboard stuff, but you might get some results using an array.

quote:
control/element builder
You'll need to dynamically write an interface window to a file (eg. "WndTestUserID.xml"), load it and get some workaround for the events of a specific control.

Furthermore, I got the following message:

[Image: attachment.php?pid=990190]

You could make some entries in ScriptInfo.xml that describes the obsolete files:

XML code:
<ScriptInfo>
    [...]
    <ObsoleteFiles>
        <File>Obsolete1.js</File>
        <File>Obsolete2.xml</File>
    </ObsoleteFiles>
</ScriptInfo>

Then read the XML, and delete the files specified, if they exist.
RE: Interface Writer | [release] 2.9 | 10/03/2010 by whiz on 03-14-2010 at 11:11 AM

I'll do that in the next version, but it might be a while before I get round to it - exams and all that...  :)


RE: Interface Writer | [release] 2.9 | 10/03/2010 by whiz on 05-24-2010 at 08:38 PM

Just so you know, I'm now working on version 3.0, with some additional features, plus some tidying up of other bits.

The script now checks for obselete files, there's a new dialog class, and I'm working on multiple items on the clipboard (rather like Microsoft Office - with some sort of sidebar).  Any additional ideas welcome.

Oh, and if anyone has any idea on how to make a dynamic control/element builder (so that the user can "draw", or click where the corners should be, a control or element on the selected, exported window, and so I can get the co-ordinates), then feel free to suggest...  :)


RE: Interface Writer | [release] 2.9 | 10/03/2010 by SmokingCookie on 05-25-2010 at 07:17 PM

IIRC, matty has done a similar thing with his Screenshot sender *-)


RE: Interface Writer | [release] 2.9 | 10/03/2010 by matty on 05-25-2010 at 07:32 PM

quote:
Originally posted by SmokingCookie
IIRC, matty has done a similar thing with his Screenshot sender *-)
The selected area feature overlays a transparent window on the desktop and draws a rectangle as the user drags the mouse.
RE: Interface Writer | [release] 2.9 | 10/03/2010 by whiz on 05-26-2010 at 06:25 PM

Would it be possible to create and show a transparent window over an exported one of an unknown size (not necessarily unknown, since the user sets it, but it obviously won't be a fixed amount)?

Would it be able to "attach" to a window, or would I have to make it so the window's locked (with the LockOnClick attribute)?


RE: Interface Writer | [beta] 3.0 (+ [release] 2.9) | 17/06/2010 (+ 10/03/2010) by mynetx on 06-17-2010 at 08:26 AM

---------------------------
Interface Writer BETA | Initialization...
---------------------------
The file "Debug.log" cannot be found.  Please reinstall the script.
---------------------------
OK   
---------------------------


RE: Interface Writer | [beta] 3.0 (+ [release] 2.9) | 17/06/2010 (+ 10/03/2010) by whiz on 06-17-2010 at 08:39 AM

Fixed it, I think.  Sorry about that, forgot to make it optional.


RE: Interface Writer | [beta] 3.0 r2 | 24/07/2010 by whiz on 07-24-2010 at 04:34 PM

Okay, beta 3.0, release 2 is now available.  :D  You can sort interface contents alphabetically, manage multiple controls/elements (no editing yet, but it's coming), and a few other additions such as the status bar (which will be replacing the annoying information alerts by displaying messages quietly).

The backup system has been improved by saving on each action (keeping it up to date instantly).  There's quite a few bug fixes in there too, and I've also added comments throughout the script if you're interested.  ;)

Note that this will probably be the last beta release, since by the next one, I'll probably have it finished, so it won't be a beta any more.  :)  Just need to sort out presets and editing multiple controls/elements (might have to scrap the builder idea, unless anyone has some example code I can try out for drawing on windows and stuff).


RE: RE: Interface Writer | [beta] 3.0 r2 | 24/07/2010 by SmokingCookie on 07-25-2010 at 06:53 AM

quote:
Originally posted by whiz
I've also added comments throughout the script if you're interested.  ;)

How about inserting comments in the XML for later editing, or documentation for others? (I)
RE: Interface Writer | [beta] 3.0 r2 | 24/07/2010 by whiz on 07-25-2010 at 09:46 AM

quote:
Originally posted by SmokingCookie
How about inserting comments in the XML for later editing, or documentation for others? (I)
Documentation?  You mean I should write one, or what?
RE: Interface Writer | [beta] 3.0 r2 | 24/07/2010 by SmokingCookie on 07-25-2010 at 09:52 AM

Nope, I'll set an example:

XML code:
<!-- Change to FigureElement for testing -->
<Element xsi:type="PlaceHolderElement" Id="Nothing">
    <Position Left="103" Top="20" Width="500" Height="350">
        <Anchor Horizontal="LeftRightFixed" Vertical="TopBottomFixed"/>
    </Position>
    <Figure>
        <Rectangle/>
    </Figure>
    <Fill>
        <PlainColor>
            <BaseColor>
                <Transparency>200</Transparency>
            </BaseColor>
        </PlainColor>
    </Fill>
</Element>

The code above is taken directly from one of my interface files (well, I removed a bunch of tabs...). As you can see, I've added a bunch of XML elements that are used for FigureElements, but not for PlaceHolderElements. It'd be useful if one could add the comment at the top of the code so they won't remove the additional XML elements, in case they forget why the "useless" data is in the PlaceHolderElement.
RE: Interface Writer | [beta] 3.0 r2 | 24/07/2010 by whiz on 07-25-2010 at 10:05 AM

Ah.  :)  Okay, fair enough, I'll add that in.

...but it's not possible to load that, is it?  Based on how I load XML files, it'll end up in the window's extra code window.  :S


RE: Interface Writer | [beta] 3.0 r2 | 24/07/2010 by SmokingCookie on 07-25-2010 at 04:30 PM

I guess you could load the XML file with the ActiveXObject "Scripting.FileSystemObject", search for comment tags and -somehow- figure out for which window, control or element it is... *-)


RE: Interface Writer | [beta] 3.0 r2 | 24/07/2010 by whiz on 07-25-2010 at 04:40 PM

quote:
Originally posted by SmokingCookie
I guess you could load the XML file with the ActiveXObject "Scripting.FileSystemObject", search for comment tags and -somehow- figure out for which window, control or element it is... *-)
Nope.  Got a better way:)
RE: Interface Writer | [beta] 3.0 r2 | 24/07/2010 by SmokingCookie on 07-25-2010 at 04:44 PM

Guess that'll do it :P


RE: Interface Writer | [release] 3.0 | 22/08/2010 by whiz on 08-22-2010 at 03:28 PM

Interface Writer 3.0 is now a stable release!  :D  See the first post...