//============================================================ // // wimgtool.c - Win32 Imgtool File Association Dialog // //============================================================ // standard windows headers #define WIN32_LEAN_AND_MEAN #include #include // standard C headers #include // MESS headers #include "assoc.h" #include "wimgres.h" #include "strconv.h" #include "../imgtool.h" //============================================================ // PARAMETERS //============================================================ #define CONTROL_START 10000 //============================================================ // TYPE DEFINITIONS //============================================================ typedef struct _assocdlg_info assocdlg_info; struct _assocdlg_info { int extension_count; const char *extensions[128]; char buffer[1024]; }; //============================================================ // LOCAL VARIABLES //============================================================ static const struct win_association_info assoc_info = { TEXT("ImgtoolImage"), 0, TEXT("%1") }; //============================================================ // win_association_dialog_proc //============================================================ static INT_PTR CALLBACK win_association_dialog_proc(HWND dialog, UINT message, WPARAM wparam, LPARAM lparam) { INT_PTR rc = 0; assocdlg_info *dlginfo; HWND ok_button, cancel_button, control; LRESULT font; LONG_PTR l; RECT r1, r2; int xmargin, ymargin, y, width, i; int height = 20; int id; DWORD style; TCHAR buf[32]; BOOL is_set; BOOL currently_set; TCHAR *t_extension; switch(message) { case WM_INITDIALOG: dlginfo = (assocdlg_info *) lparam; ok_button = GetDlgItem(dialog, IDOK); cancel_button = GetDlgItem(dialog, IDCANCEL); font = SendMessage(ok_button, WM_GETFONT, 0, 0); l = (LONG_PTR) dlginfo; SetWindowLongPtr(dialog, GWLP_USERDATA, l); GetWindowRect(cancel_button, &r1); GetWindowRect(dialog, &r2); xmargin = r1.left - r2.left; ymargin = y = r1.top - r2.top - 20; width = r2.right - r2.left - xmargin * 2; for (i = 0; i < dlginfo->extension_count; i++) { style = WS_CHILD | WS_VISIBLE | BS_CHECKBOX | BS_AUTOCHECKBOX; t_extension = tstring_from_utf8(dlginfo->extensions[i]); _sntprintf(buf, sizeof(buf) / sizeof(buf[0]), TEXT(".%s"), t_extension); free(t_extension); control = CreateWindow(TEXT("BUTTON"), buf, style, xmargin, y, width, height, dialog, NULL, NULL, NULL); if (!control) return -1; if (win_is_extension_associated(&assoc_info, buf)) SendMessage(control, BM_SETCHECK, TRUE, 0); SendMessage(control, WM_SETFONT, font, 0); SetWindowLong(control, GWL_ID, CONTROL_START + i); y += height; } r1.top += y; r1.bottom += y; SetWindowPos(cancel_button, NULL, r1.left - r2.left, r1.top - r2.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); GetWindowRect(ok_button, &r1); r1.top += y; r1.bottom += y; SetWindowPos(ok_button, NULL, r1.left - r2.left, r1.top - r2.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); r2.bottom += y + r1.bottom - r1.top; SetWindowPos(dialog, NULL, 0, 0, r2.right - r2.left, r2.bottom - r2.top, SWP_NOZORDER | SWP_NOMOVE); break; case WM_COMMAND: if (HIWORD(wparam) == BN_CLICKED) { l = GetWindowLongPtr(dialog, GWLP_USERDATA); dlginfo = (assocdlg_info *) l; id = LOWORD(wparam); if ((id == IDOK) || (id == IDCANCEL)) { if (id == IDOK) { for (i = 0; i < dlginfo->extension_count; i++) { is_set = SendMessage(GetDlgItem(dialog, CONTROL_START + i), BM_GETCHECK, 0, 0); t_extension = tstring_from_utf8(dlginfo->extensions[i]); _sntprintf(buf, sizeof(buf) / sizeof(buf[0]), TEXT(".%s"), t_extension); free(t_extension); currently_set = win_is_extension_associated(&assoc_info, buf); if (is_set && !currently_set) win_associate_extension(&assoc_info, buf, TRUE); else if (!is_set && currently_set) win_associate_extension(&assoc_info, buf, FALSE); } } EndDialog(dialog, id); } } break; } return rc; } //============================================================ // extension_compare //============================================================ static int CLIB_DECL extension_compare(const void *p1, const void *p2) { const char *e1 = *((const char **) p1); const char *e2 = *((const char **) p2); return strcmp(e1, e2); } //============================================================ // setup_extensions //============================================================ static void setup_extensions(assocdlg_info *dlginfo) { const imgtool_module *module = NULL; char *s; int buffer_pos; // merge all file extensions onto one comma-delimited list for (module = imgtool_find_module(NULL); module; module = module->next) specify_extension(dlginfo->buffer, ARRAY_LENGTH(dlginfo->buffer) - 1, module->extensions); // split the comma delimited list, and convert it to a string array dlginfo->extension_count = 0; buffer_pos = 0; while(dlginfo->buffer[buffer_pos] != '\0') { // an assertion to check to see if we are out of extensions assert(dlginfo->extension_count < ARRAY_LENGTH(dlginfo->extensions)); // search for a comma, and if found null it out s = strchr(&dlginfo->buffer[buffer_pos], ','); if (s) *s = '\0'; // append this to the extensions list dlginfo->extensions[dlginfo->extension_count++] = &dlginfo->buffer[buffer_pos]; // move to next extension if (s) buffer_pos += s - &dlginfo->buffer[buffer_pos] + 1; else buffer_pos += strlen(&dlginfo->buffer[buffer_pos]); } // sort the extensions list qsort((void *) dlginfo->extensions, dlginfo->extension_count, sizeof(dlginfo->extensions[0]), extension_compare); } //============================================================ // win_association_dialog //============================================================ void win_association_dialog(HWND parent) { assocdlg_info dlginfo; // initialize data structure memset(&dlginfo, 0, sizeof(dlginfo)); setup_extensions(&dlginfo); // display dialog DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_ASSOCIATIONS), parent, win_association_dialog_proc, (LPARAM) &dlginfo); }