Skip to content
little-brother edited this page Jul 20, 2024 · 7 revisions

What is a value viewer

You can store in a database any data, especially in BLOBs. Typical usage is to store images or json. Viewer plugins provide a convenient way to view value contents e.g. with pdf-plugin you can preview pdf-content or with audio-plugin listen an audio data.

изображение

The plugin system inspired by Total Commander-plugins and this DataGrip request. At this time plugins are used only to view values, but later it may be extended to edit operation.

How to create own plugin

If you store some specific values e.g. binary structures or in own text format, then it's a good idea to make own plugin for them. The simplest way to learn it is check a code of existing plugins. Below some tips.

  1. Each plugin have to implement one function
    HWND __stdcall view (HWND hParentWnd, const unsigned char* data, int dataLen, int dataType, TCHAR* outInfo16, TCHAR* outExt16)
    
    hParentWnd is a parent window handle. You have to create a child window inside it.
    data, dataLen and dataType represent a value. dataType is one of SQLITE_TEXT or SQLITE_BLOB. If dataType equals to SQLITE_TEXT then data contains TCHAR (is equal to wchar_t with UNICODE-macros)-string.
    outInfo16 is an output string that will be shown in the left bottom corner. Max length is 255.
    outExt16 defines a file extension when the value will be saved as a file e.g. txt.
  2. You can free resources in int __stdcall close (HWND hPluginWnd) - function.
  3. Plugins have a priority (high priority plugins are loaded first). To set the plugin priority implement int __stdcall getPriority (). It's recommended to allow to user to change the priority via ini-file.
  4. All standard plugins use ini-file to store their settings (often it has just a priority). Typical ini-file for plugin-name is below (don't forget to provide a section):
    [plugin-name]
    priority=10
    another-option=ABC
    
  5. Keep in mind: Windows UI uses UTF16LE (wchar_t). It means that each symbol is stored in 2 bytes. The recommended codepage for SQLite3 is UTF8 where each symbol required 1-4 bytes. To convert betweem UTF16 and UTF8 you can use the next functions:
#define UNICODE
#define _UNICODE
...
TCHAR* utf8to16(const char* in) {
	TCHAR *out;
	if (!in || strlen(in) == 0) {
		out = (TCHAR*)calloc (1, sizeof (TCHAR));
	} else  {
		DWORD size = MultiByteToWideChar(CP_UTF8, 0, in, -1, NULL, 0);
		out = (TCHAR*)calloc (size, sizeof (TCHAR));
		MultiByteToWideChar(CP_UTF8, 0, in, -1, out, size);
	}
	return out;
}

char* utf16to8(const TCHAR* in) {
	char* out;
	if (!in || _tcslen(in) == 0) {
		out = (char*)calloc (1, sizeof(char));
	} else  {
		int len = WideCharToMultiByte(CP_UTF8, 0, in, -1, NULL, 0, 0, 0);
		out = (char*)calloc (len, sizeof(char));
		WideCharToMultiByte(CP_UTF8, 0, in, -1, out, len, 0, 0);
	}
	return out;
}
...
TCHAR* str = utf8to16("Привет мир");
_tprintf(str); // do smth with UTF16-string
free(str); // release memory

Clone this wiki locally