#include <stdio.h>
#include <stdlib.h>
+#include <ctype.h>
#include <windows.h>
#include "widgets.h"
#include "rawdisk.h"
static struct wgt_window *win;
static struct wgt_widget *lb_instto, *bn_inst, *bn_cancel, *cb_devs, *ck_usbonly;
+
static struct rawdisk_device rawdev[64];
+static const char *items[64];
static int num_rawdev;
+
+static void update_disks(void);
static void onclick(struct wgt_widget *w);
static void onmodify(struct wgt_widget *w);
+
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprevinst, char *cmdline, int showcmd)
{
- int i, x, y;
+ int x, y;
MSG msg;
- static const char *items[64];
- if((num_rawdev = rawdisk_detect(rawdev, sizeof rawdev / sizeof *rawdev)) == -1) {
- return 1;
- }
- for(i=0; i<num_rawdev; i++) {
- items[i] = rawdev[i].name;
- }
if(!(win = wgt_window("256boss USB stick installer", 400, 300))) {
return 1;
lb_instto = wgt_label(win, "Install to device:", 10, 10);
x = wgt_xpos_after(lb_instto, WGT_AUTO);
- cb_devs = wgt_combo(win, items, num_rawdev, 0, x, 10, WGT_AUTOMIN(30), WGT_AUTO,
- onmodify);
+ cb_devs = wgt_combo(win, items, num_rawdev, 0, x, 10, 200, WGT_AUTO, onmodify);
y = wgt_ypos_after(cb_devs, 16);
ck_usbonly = wgt_checkbox(win, "only show USB devices", 1, x, y,
x = wgt_xpos_after(bn_inst, WGT_AUTO);
bn_cancel = wgt_button(win, "Cancel", x, y, WGT_AUTO, WGT_AUTO, onclick);
- if(!num_rawdev) {
- wgt_disable_widget(cb_devs);
- wgt_disable_widget(bn_inst);
- }
+ update_disks();
while(GetMessage(&msg, 0, 0, 0)) {
TranslateMessage(&msg);
return 0;
}
+static int isusbdev(struct rawdisk_device *dev)
+{
+ char *ptr = dev->path;
+ while(*ptr) {
+ int i;
+ char buf[3];
+ for(i=0; i<3; i++) {
+ buf[i] = tolower(ptr[i]);
+ }
+ if(memcmp(buf, "usb", 3) == 0) {
+ return 1;
+ }
+ ptr++;
+ }
+ return 0;
+}
+
+static void update_disks(void)
+{
+ int i;
+
+ for(i=0; i<num_rawdev; i++) {
+ free(rawdev[i].name);
+ free(rawdev[i].path);
+ }
+
+ if((num_rawdev = rawdisk_detect(rawdev, sizeof rawdev / sizeof *rawdev)) == -1) {
+ MessageBox(0, "Failed to detect storage devices!", 0, MB_OK);
+ exit(1);
+ }
+
+ if(wgt_checkbox_checked(ck_usbonly)) {
+ for(i=0; i<num_rawdev; i++) {
+ if(!isusbdev(rawdev + i)) {
+ free(rawdev[i].name);
+ free(rawdev[i].path);
+ rawdev[i] = rawdev[--num_rawdev];
+ }
+ }
+ }
+
+ for(i=0; i<num_rawdev; i++) {
+ items[i] = rawdev[i].name;
+ }
+
+ wgt_combo_setitems(cb_devs, items, num_rawdev);
+
+ if(num_rawdev) {
+ wgt_enable_widget(cb_devs);
+ wgt_enable_widget(bn_inst);
+ } else {
+ wgt_disable_widget(cb_devs);
+ wgt_disable_widget(bn_inst);
+ }
+}
+
static void onclick(struct wgt_widget *w)
{
- MessageBox(0, "clicked", "clicked", MB_OK);
+ if(w == bn_inst) {
+ MessageBox(0, "clicked", "clicked", MB_OK);
+ } else if(w == bn_cancel) {
+ PostQuitMessage(0);
+ } else if(w == ck_usbonly) {
+ update_disks();
+ }
}
static void onmodify(struct wgt_widget *w)
return w;
}
-struct wgt_widget *wgt_combo(struct wgt_window *win, const char **items, int num_items,
- int sel, int x, int y, int width, int height, wgt_callback modfunc)
+static void combosize(struct wgt_window *win, const char **items, int num_items,
+ int width, int height, struct wgt_rect *sz)
{
- int i, max_width, max_height, sum_height, res;
- struct wgt_widget *w;
+ int i, max_width, max_height, sum_height;
struct wgt_rect textsz;
- if(!(w = calloc(1, sizeof *w))) {
- fprintf(stderr, "wgt_combo: failed to allocate widget structure\n");
- return 0;
- }
- w->win = win;
-
- if(!(w->itemlist = malloc(num_items * sizeof *w->itemlist))) {
- fprintf(stderr, "wgt_combo: failed to allocate item list\n");
- free(w);
- return 0;
- }
-
wgt_string_size(win, "00", &textsz);
max_width = width < 0 && width != WGT_AUTO ? -width : textsz.width;
max_height = height < 0 && height != WGT_AUTO ? -height : textsz.height;
if(width < 0) width = max_width * 3 / 2;
if(height < 0) height = sum_height * 2;
+ sz->width = width;
+ sz->y = max_height;
+ sz->height = height;
+}
+
+struct wgt_widget *wgt_combo(struct wgt_window *win, const char **items, int num_items,
+ int sel, int x, int y, int width, int height, wgt_callback modfunc)
+{
+ int i, res;
+ struct wgt_widget *w;
+ struct wgt_rect rect;
+
+ if(!(w = calloc(1, sizeof *w))) {
+ fprintf(stderr, "wgt_combo: failed to allocate widget structure\n");
+ return 0;
+ }
+ w->win = win;
+
+ if(!(w->itemlist = malloc(num_items * sizeof *w->itemlist))) {
+ fprintf(stderr, "wgt_combo: failed to allocate item list\n");
+ free(w);
+ return 0;
+ }
+
+ combosize(win, items, num_items, width, height, &rect);
if(!(w->handle = CreateWindow("COMBOBOX", items[0] ? items[0] : "",
WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
- x, y, width, height, win->handle, 0, GetModuleHandle(0), 0))) {
+ x, y, rect.width, rect.height, win->handle, 0, GetModuleHandle(0), 0))) {
fprintf(stderr, "wgt_combo: failed to create window\n");
free(w);
return 0;
w->rect.x = x;
w->rect.y = y;
- w->rect.width = width;
- w->rect.height = max_height;
+ w->rect.width = rect.width;
+ w->rect.height = rect.y; /* single line height for layout purposes */
w->cb_modify = modfunc;
w->next = win->wlist;
return w;
}
+void wgt_checkbox_check(struct wgt_widget *w)
+{
+ SendMessage(w->handle, BM_SETCHECK, BST_CHECKED, 0);
+}
+
+void wgt_checkbox_uncheck(struct wgt_widget *w)
+{
+ SendMessage(w->handle, BM_SETCHECK, BST_UNCHECKED, 0);
+}
+
+int wgt_checkbox_checked(struct wgt_widget *w)
+{
+ return SendMessage(w->handle, BM_GETCHECK, 0, 0) == BST_CHECKED;
+}
+
+int wgt_combo_setitems(struct wgt_widget *w, const char **items, int num_items)
+{
+ int i;
+ char **newit;
+ struct wgt_rect size;
+
+ if(!(newit = malloc(num_items * sizeof *newit))) {
+ fprintf(stderr, "wgt_combo_setitems: failed to allocate item list\n");
+ return -1;
+ }
+ for(i=0; i<num_items; i++) {
+ if(!(newit[i] = strdup(items[i]))) {
+ fprintf(stderr, "wgt_combo_setitems: failed to allocate item\n");
+ while(--i >= 0) {
+ free(newit[i]);
+ }
+ free(newit);
+ return -1;
+ }
+ }
+
+ for(i=0; i<w->num_items; i++) {
+ free(w->itemlist[i]);
+ }
+ free(w->itemlist);
+ SendMessage(w->handle, CB_RESETCONTENT, 0, 0);
+
+ w->itemlist = newit;
+ w->num_items = num_items;
+
+ for(i=0; i<num_items; i++) {
+ SendMessage(w->handle, CB_ADDSTRING, 0, (long)w->itemlist[i]);
+ }
+
+ combosize(w->win, items, num_items, w->rect.width, WGT_AUTO, &size);
+ MoveWindow(w->handle, w->rect.x, w->rect.y, w->rect.width, size.height, TRUE);
+ return 0;
+}
+
int wgt_combo_selected(struct wgt_widget *w)
{
int sel = SendMessage(w->handle, CB_GETCURSEL, 0, 0);