added winapi implementation draft
This commit is contained in:
3
Makefile
3
Makefile
@@ -1,5 +1,5 @@
|
|||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
TRAY_CFLAGS :=
|
TRAY_CFLAGS := -DTRAY_WINAPI=1
|
||||||
TRAY_LDFLAGS :=
|
TRAY_LDFLAGS :=
|
||||||
else
|
else
|
||||||
UNAME_S := $(shell uname -s)
|
UNAME_S := $(shell uname -s)
|
||||||
@@ -18,7 +18,6 @@ CFLAGS := -g -Wall $(TRAY_CFLAGS)
|
|||||||
LDFLAGS := -g $(TRAY_LDFLAGS)
|
LDFLAGS := -g $(TRAY_LDFLAGS)
|
||||||
|
|
||||||
all: example
|
all: example
|
||||||
|
|
||||||
example: example.o
|
example: example.o
|
||||||
$(CC) $^ $(LDFLAGS) -o $@
|
$(CC) $^ $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
|||||||
14
example.c
14
example.c
@@ -1,4 +1,5 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "tray.h"
|
#include "tray.h"
|
||||||
|
|
||||||
@@ -20,14 +21,23 @@ static void quit_cb(struct tray_menu *item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct tray tray = {
|
static struct tray tray = {
|
||||||
.icon = "indicator-messages-new",
|
|
||||||
.menu = (struct tray_menu[]){{NULL, "Hello", 0, hello_cb, NULL},
|
.menu = (struct tray_menu[]){{NULL, "Hello", 0, hello_cb, NULL},
|
||||||
{NULL, "Quit", 0, quit_cb, NULL},
|
{NULL, "Quit", 0, quit_cb, NULL},
|
||||||
{NULL, NULL, 0, NULL, NULL}},
|
{NULL, NULL, 0, NULL, NULL}},
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
tray_init(&tray);
|
#if TRAY_APPINDICATOR
|
||||||
|
tray.icon = "indicator-messages-new";
|
||||||
|
#elif TRAY_COCOA
|
||||||
|
tray.icon = "icon.png";
|
||||||
|
#elif TRAY_WINAPI
|
||||||
|
tray.icon = "icon.ico";
|
||||||
|
#endif
|
||||||
|
if (tray_init(&tray) < 0) {
|
||||||
|
printf("failed to create tray\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
while (tray_loop(1) == 0) {
|
while (tray_loop(1) == 0) {
|
||||||
printf("iteration\n");
|
printf("iteration\n");
|
||||||
}
|
}
|
||||||
|
|||||||
117
tray.h
117
tray.h
@@ -146,6 +146,123 @@ static void tray_update(struct tray *tray) {
|
|||||||
static void tray_exit() { [NSApp terminate:NSApp]; }
|
static void tray_exit() { [NSApp terminate:NSApp]; }
|
||||||
|
|
||||||
#elif defined(TRAY_WINAPI)
|
#elif defined(TRAY_WINAPI)
|
||||||
|
#include <windows.h>
|
||||||
|
#include <shellapi.h>
|
||||||
|
|
||||||
|
#define WM_TRAY_CALLBACK_MESSAGE (WM_USER + 1)
|
||||||
|
#define WC_TRAY_CLASS_NAME "TRAY"
|
||||||
|
#define ID_TRAY_FIRST 1000
|
||||||
|
|
||||||
|
static WNDCLASSEX wc;
|
||||||
|
static NOTIFYICONDATA nid;
|
||||||
|
static HWND hwnd;
|
||||||
|
static HMENU hmenu;
|
||||||
|
|
||||||
|
static LRESULT CALLBACK _tray_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||||
|
switch (msg) {
|
||||||
|
case WM_CLOSE:
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
return 0;
|
||||||
|
case WM_DESTROY:
|
||||||
|
PostQuitMessage(0);
|
||||||
|
return 0;
|
||||||
|
case WM_TRAY_CALLBACK_MESSAGE:
|
||||||
|
if (lparam == WM_LBUTTONUP || lparam == WM_RBUTTONUP) {
|
||||||
|
POINT p;
|
||||||
|
GetCursorPos(&p);
|
||||||
|
WORD cmd = TrackPopupMenu(hmenu,
|
||||||
|
TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY,
|
||||||
|
p.x, p.y, 0, hwnd, NULL);
|
||||||
|
SendMessage(hwnd, WM_COMMAND, cmd, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WM_COMMAND:
|
||||||
|
if (wparam >= ID_TRAY_FIRST) {
|
||||||
|
MENUITEMINFO item = {
|
||||||
|
.cbSize = sizeof(MENUITEMINFO),
|
||||||
|
.fMask = MIIM_ID | MIIM_DATA,
|
||||||
|
};
|
||||||
|
if (GetMenuItemInfo(hmenu, wparam, FALSE, &item)) {
|
||||||
|
struct tray_menu *menu = (struct tray_menu *) item.dwItemData;
|
||||||
|
menu->cb(menu->context);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tray_init(struct tray *tray) {
|
||||||
|
memset(&wc, 0, sizeof(wc));
|
||||||
|
wc.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
wc.lpfnWndProc = _tray_wnd_proc;
|
||||||
|
wc.hInstance = GetModuleHandle(NULL);
|
||||||
|
wc.lpszClassName = WC_TRAY_CLASS_NAME;
|
||||||
|
if (!RegisterClassEx(&wc)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hwnd = CreateWindowEx(0, WC_TRAY_CLASS_NAME, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
if (hwnd == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
UpdateWindow(hwnd);
|
||||||
|
|
||||||
|
memset(&nid, 0, sizeof(nid));
|
||||||
|
nid.cbSize = sizeof(NOTIFYICONDATA);
|
||||||
|
nid.hWnd = hwnd;
|
||||||
|
nid.uID = 0;
|
||||||
|
nid.uFlags = NIF_ICON | NIF_MESSAGE;
|
||||||
|
nid.uCallbackMessage = WM_TRAY_CALLBACK_MESSAGE;
|
||||||
|
Shell_NotifyIcon(NIM_ADD, &nid);
|
||||||
|
|
||||||
|
tray_update(tray);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tray_loop(int blocking) {
|
||||||
|
MSG msg;
|
||||||
|
if (GetMessage(&msg, NULL, 0, 0)) {
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tray_update(struct tray *tray) {
|
||||||
|
int i = 0;
|
||||||
|
hmenu = CreatePopupMenu();
|
||||||
|
for (struct tray_menu *m = tray->menu; m != NULL && m->text != NULL; m++) {
|
||||||
|
MENUITEMINFO *item = (MENUITEMINFO *) malloc(sizeof(MENUITEMINFO));
|
||||||
|
item->cbSize = sizeof(MENUITEMINFO);
|
||||||
|
item->fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
|
||||||
|
item->fType = 0;
|
||||||
|
item->fState = 0;
|
||||||
|
item->wID = i + ID_TRAY_FIRST;
|
||||||
|
item->dwTypeData = m->text;
|
||||||
|
item->dwItemData = (ULONG_PTR) m;
|
||||||
|
|
||||||
|
InsertMenuItem(hmenu, i, TRUE, item);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
SendMessage(hwnd, WM_INITMENUPOPUP, (WPARAM)hmenu, 0);
|
||||||
|
ExtractIconEx(tray->icon, 0, NULL, &(nid.hIcon), 1);
|
||||||
|
Shell_NotifyIcon(NIM_MODIFY, &nid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tray_exit() {
|
||||||
|
Shell_NotifyIcon(NIM_DELETE, &nid);
|
||||||
|
if (nid.hIcon != 0) {
|
||||||
|
DestroyIcon(nid.hIcon);
|
||||||
|
}
|
||||||
|
if (hmenu != 0) {
|
||||||
|
DestroyMenu(hmenu);
|
||||||
|
}
|
||||||
|
PostQuitMessage(0);
|
||||||
|
UnregisterClass(WC_TRAY_CLASS_NAME, GetModuleHandle(NULL));
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user