This is going to be a long post. If I refer to bb4win it is intended as the original shell. Refering to xoblite is obvious. If I refer to bbLean, I am including its derivatives unless otherwise stated.
There have been several inquiries regarding unicode versions of blackbox, for better support of international languages. Having a unicode capable blackbox will require the following 3 things
- Unicode capable extensions need to be added to the API, to allow proper transfer of information between the core and plugins
- The core internals need to modified/updated to work with unicode strings
- Plugins need to be modified/updated to use the unicode API portions, as well as to use unicode internally.
Regarding 2 and 3 : Having the core and/or plugins compiles to use the Unicode windows API (the *W versions of functions) can be done without breaking compatibility with pre-unicode windows version (95, 98, and ME). The only requirement is to add support for the MSLU to the relevant program/plugin. Due to the loading methods employed in MSLU it has a tendency to make things crash more easily if they are doing incorrect things (such as using a NULL function pointer). If the plugin is correctly written it will not introduce any problems.
Before 2 can really be addressed (and certainly before 3), we need to try to come to an agreement on what the unicode extensions to the API will look like.
Several functions such as ReadBool, WriteInt etc that are almost completely string base will probably be best added as ReadBoolW, WriteIntW etc with the string just being WCHAR strings instead of the current CHAR strings.
The part of the API that I would actually like to discuss are the Tray and Task portions of the API. These are probably the two most critical components in future unicode versions. What I would like to suggest for these two sections is that we consider a new design for these API functions, rather than just changing string types in the existing functions.
Tray Icon APIThe current API consists of
- struct systemTray
- int GetTraySize(void)
- systemTray* GetTrayIcon(int pointer)
- The BB_TRAYUPDATE message, with lParam to indicate the update type
There are several problems with this design, some of which may just be my personla option. These problems are
- struct systemTray is different between branches (different additions at the end). This makes writing a plugin supporting balloon tooltips under both xoblite and bbLean difficult. It also makes any additions to this structure practically impossible, without breaking compatibility.
- The fact that we must return a systemTray * forces the core to either use that data structure internally, or otherwise to populate it when requested
- There is no guaranteed why to find the info on a tray icon, other than to cycle through with a for loop
- The wParam for the BB_TRAYUPDATE message is not currently compatible across branches, making it practically useless (bbLean fills it with flags on adds and modifies and a 0 on removes, bb4win puts a systemTray * to indicate the affected item on all messages, xoblite bb3 puts a systemTray * on modifies and 0 otherwise)
Proposed tray APIGetTraySize is not affected by this and serves the same purpose under the new unicode capable API as before.
Replace GetTrayIcon with 3 new functions, similar to GetSettingPtr. These functions are internally very simliar to each other, the only difference being how they identify what icon to retrieve information on. The first function would have a prototype
Code:
BOOL GetTrayInfo(HWND hWnd, UINT uID, void **trayInfo, INT *infoTypes, INT numInfo)
hWnd: Window to which the tray icon belongs
uID:ID of the icon
trayInfo: The calling plugin allocates an array of void *'s, the size of which is numInfo. This function will fill this array with pointers to the requested information.
infoTypes: A plugin allocated array of integers indicating what information is wanted on the tray icon. The values used will be discussed later
numInfo: The number of pieces of information requested (size of arrays)
Return value: TRUE if the referenced icon exits, indicating that information is filled in. FALSE if the icon does not exits.
The second function would have a prototype
Code:
BOOL GetTrayInfoIndexed(UINT index, void **trayInfo, INT *infoTypes, INT numInfo)
index: An index into the list of icons. Same purpose as in current GetTrayIcon
trayInfo: The calling plugin allocates an array of void *'s, the size of which is numInfo. This function will fill this array with pointers to the requested information.
infoTypes: A plugin allocated array of integers indicating what information is wanted on the tray icon. The values used will be discussed later
numInfo: The number of pieces of information requested (size of arrays)
Return value: TRUE if the referenced icon exits, indicating that information is filled in. FALSE if the icon does not exits.
The third function would have a prototype
Code:
BOOL GetTrayInfoMsg(WPARAM wParam, void **trayInfo, INT *infoTypes, INT numInfo)
wParam: The wParam recieved in a BB_TRAYUPDATE message. Under this API, there is no specific requiremnt on what is in this parameter, but it must allow the core to identify an icon. The most common choice would probably be a pointer to an internal data structure, or some construct of hWnd and uID.
trayInfo: The calling plugin allocates an array of void *'s, the size of which is numInfo. This function will fill this array with pointers to the requested information.
infoTypes: A plugin allocated array of integers indicating what information is wanted on the tray icon. The values used will be discussed later
numInfo: The number of pieces of information requested (size of arrays).
Return value: TRUE if the referenced icon exits, indicating that information is filled in. FALSE if the icon does not exits.
Why 3 functions?The second function (UINT index) is intended for plugin startup, and is intended for use in a for loop. The third function (WPARAM wParam) would typically be used to create new icons and update existing icons. The first function (HWND hWnd, UINT uID) is an alternative to allow for icon updating. It also provides an easy way to test for existence of an earlier icon.
Where do the values for infoTypes come from?I propose that we not define them in a header the way we currently do for GetSettingPtr. I would like to propose a more flexible approach. The core creates these integers using AddAtom("TrayIcon::AnsiTip"), addAtom("TrayIcon::Icon") etc. When a plugin loads it calls FindAtom("TrayIcon::UnicodeTip"). If FindAtom returns 0, then that property is not supported by the core. If FindAtom returns a number, that is the integer to use for fetching that property. Atoms are case insensitive and the application can use up to approximately 16,000 string atoms
This system provides inherent feature checking for plugins on what the core supports. It also prevents cases where one brnch has defined a constant as one value, and a different branch has used a different value.
Difficulty of implementationFunction 1 and 2 would be easily implemented as a wrapper over the existing api functions. It would thus be very easy to add these function to existing branches, which would support the properties
- TrayIcon::hWnd
- TrayIcon::ID
- TrayIcon::CallbackMsg
- TrayIcon::Icon
- TrayIcon::AnsiToolTip
Properties for balloon tooltips could also be added to most branches without any internal changes except these new functions.
Function 3 would require that all branches agree to the definition of the WParam for BB_TRAYUPDATE. It is however not critical, so can be dropped if this is a problem.
Task APIThe idea for the new task API would have the same structure as the tray api described above. Only one function would be needed, as the tasks HWND is a unique descriptor and is already included as the wParam for almost all BB_TASKUPDATE messages.
Code:
BOOL GetTaskInfo(HWND hWnd, void **trayInfo, INT *infoTypes, INT numInfo)
Possibly a SetTaskInfo function with these same paramters could also be added, if desired.
How do the other dev's feel about a unicode api, and the above proposal?
EDIT 1:
unkamunka wrote:
This is a placeholder until I get back online next week:
- unicode support is long overdue - thanks for starting the ball rolling
- using phrases such a "the fault of" tends to draw my instant disagreement - no matter which coder was involved
- some aspects of the API creak badly with age
Replaced the fault part with an explanation of the differences (this regards the wParam of BB_TRAYUPDATE messages). It wasn't intended to place blame, merely to indicate which branch had made the most incompatible changes. Fault won't appear again.