Blog Navigator Professional posts again

Security versus compatibility and functionality. Is removing features a new course for Microsoft?

Originally posted on JoeUser.com

Last week it has been brought to my attention that our Blog Navigator can no longer post web articles. Alas, this was only a symptom of a much worse disease, but first things first…

This month in a noble effort of making the Windows platform more secure for us and our (perhaps future) kids ;) Microsoft rolled out a new set of updates, among which is this one innocently called MS05-013 and located in Microsoft Knowledge Base under a mysterious KB891781.

You will find more about the update and the horror it caused among the programmers using the control affected by the update on usenet, posts as this and this are only small sample of the damage. It seems that MS broke quite a few programs while making us more safe.

The effect, saying it bluntly is: IDHTMLEdit has been made useless and Blog Navigator fallen prey to that change.

Since IDHTMLEdit is simply a wrapper around MSHTML editor, I’ve examined quite a few approaches and some existing libraries, to fix the issue as fast and with as little modifications to the existing code as possible. After a day of hunting around and testing the existing approaches I’ve decided that if I want to retain the control over my code and keep it at a reasonable size, I need to do it myself.

Below is my simplistic (and working) approach to migrating from DHTML Editing Component to MSHTML editor (for Delphi programmers).

  1. I use a TEmbeddedWB as the web browser control wrapper as it offers quite a bit additional functionality. I’m assuming you use that instead of the TWebbrowser as well. If you’re not, it’a not a big problem to extract the functionalty you will need here.
  2. In the DhtmlEdit you operate on the DOM structure and that’s the interface the control does not allow you to access any loger and the change thaat makes it useless. The TWebBrowser offers a Document IDispatch which you can cast on IHTMLDocument2. This is exactly the structure you were working on before.
  3. Now the browser control itself does not offer the ExecCommand(…) functionality. but not all is lost. when you get to the IHTMLDocument2 interface as described before, you can pretty much do anythng you were doing before by calling its execCommand.
  4. You can also pull ann the formatting data from it by querrying it with its: queryCommandEnabled, execCommand, queryCommandIndeterm, queryCommandState, queryCommandSupported, queryCommandText and queryCommandValue methods.
  5. Now the problem is that IDHTMLEdit used numeric values while the Document requires you to use strings. The simplest method is to use a translating table which is what I did:
type
  TMSHtmlCommandTranslation = array [DECMD_BOLD .. DECMD_PROPERTIES] of WideString;
const
  MSHtmlCommandTranslation : TMSHtmlCommandTranslation = (
  'Bold',               //DECMD_BOLD = $00001388;
  '',                   //
  'Copy',               //DECMD_COPY = $0000138A;
  'Cut',                //DECMD_CUT = $0000138B;
  'Delete',             //DDECMD_DELETE = $0000138C;
  '',                   //DDECMD_DELETECELLS = $0000138D;
  '',                   //DDECMD_DELETECOLS = $0000138E;
  '',                   //DDECMD_DELETEROWS = $0000138F;
  'Find',               //DDECMD_FINDTEXT = $00001390;
  'FontName',           //DDECMD_FONT = $00001391;
  '',                   //DDECMD_GETBACKCOLOR = $00001392;
  '',                   //DDECMD_GETBLOCKFMT = $00001393;
  '',                   //DDECMD_GETBLOCKFMTNAMES = $00001394;
  '',                   //DDECMD_GETFONTNAME = $00001395;
  'FontSize',           //DDECMD_GETFONTSIZE = $00001396;
  '',                   //DDECMD_GETFORECOLOR = $00001397;
  'CreateLink',         //DDECMD_HYPERLINK = $00001398;
  'InsertImage',        //DDECMD_IMAGE = $00001399;
  'Indent',             //DDECMD_INDENT = $0000139A;
  '',                   //DDECMD_INSERTCELL = $0000139B;
  '',                   //DDECMD_INSERTCOL = $0000139C;
  '',                   //DDECMD_INSERTROW = $0000139D;
  '',                   //DDECMD_INSERTTABLE = $0000139E;
  'Italic',             //DDECMD_ITALIC = $0000139F;
  'JustifyCenter',      //DDECMD_JUSTIFYCENTER = $000013A0;
  'JustifyLeft',        //DDECMD_JUSTIFYLEFT = $000013A1;
  'JustifyRight',       //DDECMD_JUSTIFYRIGHT = $000013A2;
  '',                   //DDECMD_LOCK_ELEMENT = $000013A3;
  '',                   //DDECMD_MAKE_ABSOLUTE = $000013A4;
  '',                   //DDECMD_MERGECELLS = $000013A5;
  'InsertOrderedList', //DDECMD_ORDERLIST = $000013A6;
  'Outdent',            //DDECMD_OUTDENT = $000013A7;
  'Paste',              //DDECMD_PASTE = $000013A8;
  'Redo',               //DDECMD_REDO = $000013A9;
  '',                   //DDECMD_REMOVEFORMAT = $000013AA;
  'SelectAll',          //DDECMD_SELECTALL = $000013AB;
  '',                   //DDECMD_SEND_BACKWARD = $000013AC;
  '',                   //DDECMD_BRING_FORWARD = $000013AD;
  '',                   //DDECMD_SEND_BELOW_TEXT = $000013AE;
  '',                   //DDECMD_BRING_ABOVE_TEXT = $000013AF;
  '',                   //DDECMD_SEND_TO_BACK = $000013B0;
  '',                   //DDECMD_BRING_TO_FRONT = $000013B1;
  '',                   //DDECMD_SETBACKCOLOR = $000013B2;
  '',                   //DDECMD_SETBLOCKFMT = $000013B3;
  'FontName',           //DDECMD_SETFONTNAME = $000013B4;
  'FontSize',           //DDECMD_SETFONTSIZE = $000013B5;
  'ForeColor',          //DDECMD_SETFORECOLOR = $000013B6;
  '',                   //DDECMD_SPLITCELL = $000013B7;
  'Underline',          //DDECMD_UNDERLINE = $000013B8;
  'Undo',               //DDECMD_UNDO = $000013B9;
  'Unlink',             //DDECMD_UNLINK = $000013BA;
  'InsertUnorderedList',//DDECMD_UNORDERLIST = $000013BB;
  '');                  //DECMD_PROPERTIES = $000013BC;

I store the command values as the controls Tags so now instead of calling:

DHTMLEdit.ExecCommand(TControl(Sender).Tag,OLECMDEXECOPT_DODEFAULT);

I simply call:

FDocument.execCommand(MSHtmlCommandTranslation[TControl(Sender).Tag],True,variant)

where the FDocument is the IHTMLDocument2 DOM document I extracted from the TWebBrowser for the sake of not having to cast it each time I use it. and instead of:

DHTMLEdit.QueryStatus(TControl(Sender).Tag);

I can now use:

 FDocument.queryCommandValue(MSHtmlCommandTranslation[TControl(Sender).Tag]);
 FDocument.queryCommandEnabled(MSHtmlCommandTranslation[TControl(Sender).Tag]);

this allowed me to migrate away from DHTML Editing Component within one day after shunning all other options).

One thing that was pretty indispensible for DHTML Editing Component was that it called me back evary time a blok formatting was changed, it had this useful OnDisplayChanged event which was summoned every time the UI needed updating. That’s where TEmbeddedWB comes handy it implements a

function UpdateUI: HRESULT; stdcall;

which than triggers the OnUpdateUI event, which for our needs does exactly the save what the OnDisplayChanged event did. so you can simply call your previous OnDisplayChanged event with the numerical querries remapped to strings and… with minimal effort you have your control fully migrated to the MSHTML editor.

So… this post is the first post made with the updated Blog Navigator with its poat editong brought back to normal functionality.

Posted in Blog Navigator, Delphi, Software Development, Web applications
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...
| 9 Comments »

How big is that thing anyway?

Making sure everything in place, just where it should be.

Originally posted on Wincustomize.com

Implementing FireFox support in SkinStudio and having to calculate everyting carefully in the process I got pretty tired of being unable to tell how wide something is or having to run a separate app for it. Is there one actually? I guess there is… perhaps even skinnable. But being where I am – I wanted it integrated and easy to use for myself and for every skiner. available instantaneously. Seamlessly integrated into Skinstudio. (This will be available in the next SkinStudio release),

So here’s my attempt at counting pixels.

You probably already used Skinstudio zooming tool, and you’ve noticed that apart from magnifying the screen it also tells you the color of a pixel under the cursor.

now if you press the Ctrl key it will start to measure whatever you have highlighted

As you can see – additionally to the RGB values, now you also have the “Width” and “Height” values. Now, while still having the Ctrl key pressed, let me move the cursor down and right a bit…

as you can see, the Width and Height values show the difference between what was the mouse position when you pressed the “Ctrl” key and what it is now. The size is measured as long as you hol the “Ctrl:” button pressed.

Posted in IconDeveloper, SkinStudio
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...
| Leave a Comment »

New WindowBlinds window frame possiblities

How WindowBlinds 4.5 made the window frames even more frolicsome.

Originally posted on Wincustomize.com

WindowBlinds 4.5 introduced two new cool tricks for window frames –

  • IE/Explorer special shell frames, and
  • random frames.

The two features are mutually exclusive, meaning that if you use random frames you cannot specify the special frames for the shell windows.
First of all – both features are only available in the UIS2 skins (Advanced WindowBlinds skinning format).

Now let me explain how you can use/access the features in SkinStudio and what exactly do they do:

1) Shell windows

Those are the system windows that you browse/explore your computer and the Internet with. SkinStudio added a special section for referencing them placed in the tree in this node: “Window Borders”->”Frames for Shell Windows”. The section defines two attributes:

  • “Explorer Active Windows”
  • “Explorer Inactive Windows”

The names are pretty self explanatory. The attributes define the indexes of the states used for the active and inactive shell windows. But what you may find confusing is that the index is zero based – meaning that the first state in your frame set has an index of 0. If you define the attributes WindowBlinds will choose those states for shell windows instead of it’s regular choice being – the first state for active and the last one for inactive windows.

What you need to do is simply make your window frame images contain two more states for the shell windows so instead of 2 or 3 (if you define the disabled state) images you would include normally – you put 4 or 5 states in there. Of course the states layout setup cannot violate the 3 canonic WindowBlinds rules which are:

  • first state is for the regular active window.
  • last state is for the inactive window (or the second from the end if disabled state is used).
  • and if you have the “Disabled frame state” enabled in the skin, that is you have this attribute:
    Section: “Window Borders”-> Attribute: “Miscellaneous options”->”Image State – Disabled Frame”
    set to “Enabled”, then the “disabled state” must be added as the last state in the strip. By the way – if you never realized this before – disabled frames are used when a window is showing a modal dialog that makes this window inaccessible for the user. You can find when a window is disabled if Windows will *ding* at you when you try to click such disabled window.

So this forces us to use a following states layout:

  1. Active window
  2. Active shell window (this is the state that you need to point at in the “Explorer Active Windows” attribute – in this case you would need to set it to “1” since the index is zero based).
  3. Inactive shell window (this is the state that you need to point at in the “Explorer Inactive Windows” attribute – in this case you would need to set it to “1” since the index is zero based).
  4. Inactive window state
  5. Disabled window state (if the disabled state visualization is enabled).

That’s all that it is to it. Of course you need to equip all the window edge images with the equally same states number as that’s a fundamental WindowBlinds requirement.

2) Random frames

Random frames is a feature which I personally find much cooler than the shell windows skinning. This feature actually changes the windows states layout established so long ago. You enable the feature by flipping the:

Section: “Window Borders”-> Attribute: “Miscellaneous options”->”Random frame selection”

from “Disable random borders” to “Enable random borders”.

By doing so you allow WindowBlinds to randomize the available frames looks for newly created windows. If this option is enabled, the skin must provide more than one pair of active/inactive states for windows borders. The borders must be organized in sets of pairs of active and inactive states following each other like that:

  1. active state 1
  2. inactive state 1
  3. active state 2
  4. inactive state 2
  5. active state X
  6. inactive state X

Also like previously – exactly the same number of states needs to be supplied for all edges of the window frames. Also there is another limitation here – all states must be of the same shape, which means that if you put any pink area on the frame in the active1 state – it needs to be in the exact same shape in all the active states as well and unless you enabled Dynamic frames (Section: “Window Borders”-> Attribute: “Miscellaneous options”->”Dynamic Frame Image Shape”) – it needs to be in all of the disabled states too.

WindowBlinds will choose among the pairs on a random basis during creation of each window/app.

Now if you define say… 20 framesets – the user will have a few hours of fun and surprises with the skin. I can see how this is a big job to define that number of frames, but isn’t a skin an enormous effort already? Now if you add just a little bit to it making it exceptional – don’t we all agree that it’s what lies in the heart of customization? I can see how this could be a true favorite feature (on top of the translucent start menus) in the coming months

Posted in SkinStudio, WindowBlinds
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...
| 9 Comments »