Archive for July, 2008

Trials and tribulations with WebKit

This post is about issues that pop up after you’ve got WebKit compiled and can get an application up and running within initialization errors.

(fyi, these are issues I’ve had on Win32. Things may be different on other platforms)

Issue 1: Safari theme doesn’t work, causes crash
If, like me, you’ve just copied the other necessary DLLs needed by WebKit from your Safari directory, SafariTheme.dll will cause you trouble (crash) unless you copy over the \SafariTheme.resources folder as well.

Note that WebKit will work fine without the Safari theme. Simply, get rid of the SafariTheme.dll file and a default theme will be used (it’s ugly, but it’s functional). Also, note that I’m not sure what the copyrights/license is for the Safari theme, there may be restrictions on using and/or distributing it.

Issue 2: “localized string not found” in context menus
Go to folder where you have the WebKit source. Navigate to WebKit\win. There you’ll find the \WebKit.resources folder, copy it to the folder with your WebKit DLL. Next, copy \English.lproj into the copied \WebKit.resources folder.

So, in the directory with your WebKit DLL, you should have:
\WebKit.resources
\WebKit.resources\English.lproj

Issue 3: loadURL() does nothing
If your using the WinLauncher application as guide, you’ll notice the loadURL() function doesn’t seem to work. This is because the timeout interval passed to the initWithURL() member is 0. A value of 60 (seconds?) seems to work well.

request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 60);

That’s it for now. In the next few days, I’ll post how to wrap WebKit and embed it within a WinForms application; screenshot below.

WebKit in C# WinForms application

Programmatically registering and un-registering a COM DLL

Playing around with WebKit a bit and stumbled across the headaches of working with a COM DLL. WebKit uses COM interfaces, so an application using a WebKit DLL must register the DLL. COM DLL registration is system-wide (i.e. all calls will be directed to a single DLL file), and this creates a problem if an application wants to use a DLL of a different version or a custom one (assuming renaming all the interfaces is not a viable option).

A simple solution to this seems to be to register and unregister the DLL programmatically. By doing so, any existing (or non-existent) registration is ignored and the exact DLL file the application needs is registered and used. The registration is still system-wide, but if other applications follow the same policy there doesn’t seem to be a problem. For applications that don’t follow this policy, it seems their calls will go to the last DLL registered.

(This is just from my own investigation and I really don’t know a whole lot about COM stuff. If anything mentioned is incorrect, please correct me.)

How to register and unregister COM DLLs can be found here. This is a bit convoluted. I actually just followed the steps listed in the second post of this thread on the MSDN forums to write my code.

To register:

HMODULE webKitMod = ::LoadLibrary(L"WebKit.dll"); FARPROC regFunc = ::GetProcAddress(webKitMod, "DllRegisterServer"); if(regFunc != NULL) { HRESULT regRet = regFunc(); if(regRet != S_OK) { // report error } } else { // report error } ::FreeLibrary(webKitMod);

To UnRegister:

HMODULE webKitMod = ::LoadLibrary(L"WebKit.dll"); FARPROC unRegFunc = ::GetProcAddress(webKitMod, "DllUnregisterServer"); if(unRegFunc != NULL) { HRESULT unRegRet = unRegFunc(); if(unRegRet != S_OK) { // report error } } else { // report error } ::FreeLibrary(webKitMod);

Rtf2Html 1.2

I made some updates to the lightweight rtf to html converter I created a while back.

Changes include:

  • Context menu for textboxes, making it easy to select, cut, copy, paste, etc.
  • Ability to view a preview of the output to ensure correct result.
  • String for color hex values are now simplifed, if possible. (e.g. #0000ff = #00f). This, in a small way, conserves space.
  • Support for a few basic special entities, less-than sign, greater-than sign, quotation mark, and ampersand. Also, the copyright symbol is converted into it’s appropriate special entity (this allows compatibility with older browsers and/or content w/ non-unicode character sets)
  • Conversion of newline characters to <br /> elements.
  • The executable now has a cool icon.
These are in addition to the previous formatting options supported: text color, bold, italic, underline, and strike-thru.

Not supported are: font-type, font-size, bulleted lists, paragraph alignment, bold-italic font-style. I’ll probably look into these in the future. They’re not difficult to implement, but, especially when embedding within existing HTML content, it’s beneficial to be able to toggle these options on and off (specifically off, as it may be better for the styles of the parent element to be inherited in certain cases). The work of updating the interface + implementing these additional options is more than I’d care to undertake at this time. Especially as this app is only meant to format source code that I post here.

How to open the containing folder

Opening a window showing the contents of a folder and highlighting a specific file in the folder can be a pretty useful action, especially for applications that show or list files to the user, as it allows for the user to quickly get to a file and manipulate or open it via. the operating system’s shell. The most popular implementations of this features are, perhaps, in web browsers; it’s referred to by a couple of different phrases, “Open Folder” in IE7, “Show Containing Folder” in Safari, “Open Containing Folder” in Firefox.

Anyways, I wanted this feature for something I’m working on in Windows and it’s actually pretty simple to implement, but it took me a while to find information on it. There’s no Win32 function, instead, explorer has to be run with a command-line switch. Switches and accompanying examples can be found here.

So the command to open a containing folder would be:

explorer /select, <file_path>

Here’s a bit of C# code (it should be simple to do this in almost any language):

System.Diagnostics.Process p1 = new System.Diagnostics.Process();
p1.StartInfo.FileName =
"explorer";
p1.StartInfo.Arguments =
"/select, \"" + <file_path> + "\"";
p1.StartInfo.WorkingDirectory =
Environment.GetEnvironmentVariable("SystemRoot");
p1.StartInfo.UseShellExecute =
true;
p1.Start();

Of course, replace <file_path> with the file you want highlighted.

Based on the info here, as well as the page linked to above, it seems this should work on all versions of Windows since Win 95.

More background:transparent woes in IE

A similar issue to the one I mentioned in my previous post. The problem is the same, the behavior of anchor elements is broken, however, the cause seems to be different.

background transparent issue

The image above demonstrates the issue. The area enclosed by the blue box is the anchor element. It’s a block-level element (display:block) and positioned using position:absolute. The area enclosed by the white lines is part of a paragraph element. When the paragraph element overlaps the anchor element, the functionality of the anchor element is broken (oddly, the functionality on the border of the anchor element is still active).

I’ve found two solutions.

  • Reduce the width of the paragraph element or it’s container to prevent the overlap
  • Use a transparent gif for the background of the anchor element. The same solution for the issue described in my previous post