MyRolan (快速启动小工具)

类似 Rolan的快速启动工具。

启动后隐藏,当鼠标移至左上角时,窗口显示,点击项目可运行程序。

GitHub地址: MyRolan 。

MyRolan (快速启动小工具)

 #if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif #include <tchar.h>
#include <windows.h>
#include <string>
#include <stdio.h>
#include <shellapi.h>
#include <windowsx.h>
#include <commctrl.h>
using namespace std; /* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); /* Make the class name into a global variable */
TCHAR szClassName[ ] = _T("MyRolan"); #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) typedef struct item {
string name;
string path;
string icon_path;
string arguments;
} item;
typedef struct group {
string name;
item* items;
int item_num;
} group; int WIDTH=;
int HEIGHT=;
int GROUP_WIDTH=;
int ITEM_WIDTH=;
int ITEM_HEIGHT=;
int GROUP_HEIGHT=ITEM_HEIGHT;
#define BKCOLOR RGB(240,240,240)
#define COMMON_ITEM_BKCOLOR RGB(220,220,220)
#define ACTIVE_ITEM_BKCOLOR RGB(200,200,200) group* groups;
int group_num;
int current_group=;
int current_item=;
int current_top=;
int item_columns=; int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = ; /* No extra bytes after the window class */
wincl.cbWndExtra = ; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
//wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
wincl.hbrBackground = NULL;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return ; /* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
WS_EX_TOOLWINDOW, /* Extended possibilites for variation */
szClassName, /* Classname */
_T("MyRolan"), /* Title Text */
WS_EX_TOOLWINDOW, /* default window WS_OVERLAPPEDWINDOW*/
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
WIDTH, /* The programs width */
HEIGHT, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
DWORD dwExStyle = GetWindowLong(hwnd, GWL_STYLE);
dwExStyle &=~WS_CAPTION;
SetWindowLong(hwnd, GWL_STYLE, dwExStyle); /* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow); /* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, , ))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
} /* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
void remove_nextline(char* buf) {
int l=strlen(buf);
if(buf[l-]=='\n')
buf[l-]='\0';
}
int load_data(HWND hwnd) {
FILE* f=fopen("data.txt","r");
if(f==NULL) {
MessageBox(hwnd,"Data File Not Exist.","Error!",);
return -;
}
char buf[];
fgets(buf,,f);
sscanf(buf,"%d",&group_num);
groups=new group[group_num];
for(int i=; i<group_num; i++) {
fgets(buf,,f);
remove_nextline(buf);
groups[i].name=buf;
fgets(buf,,f);
sscanf(buf,"%d",&groups[i].item_num);
groups[i].items=new item[groups[i].item_num];
for(int j=; j<groups[i].item_num; j++) {
fgets(buf,,f);
remove_nextline(buf);
groups[i].items[j].name=buf;
fgets(buf,,f);
remove_nextline(buf);
groups[i].items[j].path=buf;
fgets(buf,,f);
remove_nextline(buf);
groups[i].items[j].icon_path=buf;
fgets(buf,,f);
remove_nextline(buf);
groups[i].items[j].arguments=buf;
}
}
fclose(f);
return ;
}
long get_rect_width(RECT rect) {
return rect.right-rect.left;
} long get_rect_height(RECT rect) {
return rect.bottom-rect.top;
}
long get_client_width(HWND hwnd) {
RECT rect;
GetClientRect (hwnd, &rect) ;
return get_rect_width(rect);
} long get_client_height(HWND hwnd) {
RECT rect;
GetClientRect (hwnd, &rect) ;
return get_rect_height(rect);
}
int xy_to_num(int num,int columns,int width,int height,int x,int y) {
int c=x/width;
if(c>=columns)return -;
int r=y/height;
int n=columns*r+c;
if(n>=num)return -;
return n;
}
POINT get_client_mouse(HWND hwnd) {
POINT mouse;
GetCursorPos(&mouse);//获取鼠标的屏幕坐标
ScreenToClient(hwnd,&mouse);//转换为界面坐标
return mouse;
}
int get_current_position(HWND hwnd,int& is_group) {
POINT mouse=get_client_mouse(hwnd);
if(mouse.x<||mouse.x>WIDTH||mouse.y<||mouse.y>HEIGHT)return -;
if(mouse.x<=GROUP_WIDTH) {
is_group=;
int n=xy_to_num(group_num,,GROUP_WIDTH,GROUP_HEIGHT,mouse.x,mouse.y);
return n;
}
is_group=;
int num=groups[current_group].item_num;
int n=xy_to_num(num,item_columns,ITEM_WIDTH,ITEM_HEIGHT,mouse.x-GROUP_WIDTH,mouse.y-current_top);
return n;
}
int update_current_group_and_item(HWND hwnd) {
int current_group_bak=current_group;
int current_item_bak=current_item;
int is_group=;
int n=get_current_position(hwnd,is_group);
if(n<)return ;
if(is_group) {
current_group=n;
current_item=;
current_top=;
}
else current_item=n;
return (current_group_bak!=current_group)||(current_item_bak!=current_item)?:;
}
void paint_rolan(HWND hwnd,HDC hdc1,HDC hdc) {
static HBRUSH bk_brush =CreateSolidBrush (BKCOLOR);
static HBRUSH common_item_brush =CreateSolidBrush (COMMON_ITEM_BKCOLOR);
static HBRUSH active_item_brush =CreateSolidBrush (ACTIVE_ITEM_BKCOLOR);
static HFONT hFont;
LOGFONT lf;
lf.lfHeight=ITEM_HEIGHT/2.6;
lf.lfWidth= ;
lf.lfEscapement= ;
lf.lfOrientation= ;
lf.lfWeight=;
lf.lfItalic= ;
lf.lfUnderline= ;
lf.lfStrikeOut= ;
lf.lfCharSet=DEFAULT_CHARSET ;
lf.lfOutPrecision= ;
lf.lfClipPrecision= ;
lf.lfQuality= ;
lf.lfPitchAndFamily= ;
lstrcpy (lf.lfFaceName, _T("Arial") );
PatBlt(hdc, , , WIDTH,HEIGHT, WHITENESS); //在绘图前调用这个函数可以把背景重画,WHITENESS可以使背景透明
hFont = CreateFontIndirect (&lf) ;
SelectFont(hdc,hFont);
SelectObject (hdc, GetStockObject (NULL_PEN)) ;
SelectObject (hdc,bk_brush);
Rectangle(hdc,,,WIDTH,HEIGHT);
for(int i=; i<group_num; i++) {
if(i==current_group) {
SelectObject (hdc,active_item_brush);
SetBkColor(hdc,ACTIVE_ITEM_BKCOLOR);//设置文字背景色
} else {
SelectObject (hdc,common_item_brush);
SetBkColor(hdc,COMMON_ITEM_BKCOLOR);//设置文字背景色
}
Rectangle(hdc,,i*GROUP_HEIGHT-,GROUP_WIDTH,(i+)*GROUP_HEIGHT);
TextOut(hdc,GROUP_WIDTH/,i*GROUP_HEIGHT+GROUP_HEIGHT/,groups[i].name.c_str(),groups[i].name.length());
}
int gitem_num=groups[current_group].item_num;
item* items=groups[current_group].items;
int item_num=((gitem_num-)/item_columns+)*item_columns;
int item_count=;
while(item_count<item_num) {
int left=GROUP_WIDTH+(item_count%item_columns)*ITEM_WIDTH;
int top=current_top+item_count/item_columns*ITEM_HEIGHT;
if(item_count==current_item) {
SelectObject (hdc,active_item_brush);
SetBkColor(hdc,ACTIVE_ITEM_BKCOLOR);//设置文字背景色
} else if(item_count<gitem_num){
SelectObject (hdc,common_item_brush);
SetBkColor(hdc,COMMON_ITEM_BKCOLOR);//设置文字背景色
}else {
SelectObject (hdc,bk_brush);
}
Rectangle(hdc,left-,top-,left+ITEM_WIDTH,top+ITEM_HEIGHT);
if(item_count<gitem_num)TextOut(hdc,left+ITEM_WIDTH/,top+ITEM_HEIGHT/,items[item_count].name.c_str(),items[item_count].name.length());
item_count++;
}
BitBlt(hdc1, , , WIDTH, HEIGHT, hdc, , , SRCCOPY); //将位图直接复制在设备上,关于该函数的使用有很多说明,在这里就不再提了
}
/* This function is called by the Windows function DispatchMessage() */ string get_directory(string path){
int last=path.find_last_of('\\');
return path.substr(,last);
} LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HDC hdc;
static PAINTSTRUCT ps ;
static bool is_hide;
static int screen_height;
static bool not_program_move;
static HDC hdcBuffer;
switch (message) { /* handle the messages */
case WM_CREATE: {
not_program_move=true;
is_hide=false;
screen_height=GetSystemMetrics(SM_CYSCREEN);
load_data(hwnd);
current_group=;
current_item=;
InvalidateRect(hwnd,NULL,true);
SetTimer(hwnd,,,NULL);
hdc = GetDC(hwnd); //获取设备
hdcBuffer = CreateCompatibleDC(hdc); //给设备分配一个内存空间
HBITMAP hBitMap = CreateCompatibleBitmap(hdc, WIDTH, HEIGHT); //创建一个cxClient, cyClient大小并且适应DC设备环境的位图
ReleaseDC(hwnd, hdc);
SelectObject(hdcBuffer, hBitMap); //将位图设置为hdcBuffer的画刷
}
break;
case WM_MOVE: {
RECT rect;
GetWindowRect(hwnd,&rect);
if(not_program_move&&rect.left<=&&rect.bottom>=screen_height) {
not_program_move=false;
MoveWindow(hwnd,-WIDTH,-HEIGHT, WIDTH, HEIGHT, FALSE);// screen_height-5
not_program_move=true;
}
is_hide=true;
}
break;
case WM_KEYDOWN: { //识别按键
}
break;
case WM_PAINT: {
hdc=BeginPaint (hwnd,&ps) ;
paint_rolan(hwnd,hdc,hdcBuffer);
EndPaint(hwnd,&ps);
}
break;
case WM_TIMER: {
RECT rect;
GetClientRect(hwnd,&rect);
SetWindowPos(hwnd, HWND_TOPMOST, , , , ,SWP_NOSIZE|SWP_NOMOVE);
}
break;
case WM_MOUSELEAVE: {
not_program_move=true;
MoveWindow(hwnd,-WIDTH,-HEIGHT, WIDTH, HEIGHT, FALSE);// screen_height-5
is_hide=true;
}
break;
case WM_MOUSEHOVER:
break;
case WM_MOUSEMOVE: {
TRACKMOUSEEVENT trmouse;
trmouse.cbSize = sizeof(TRACKMOUSEEVENT);
trmouse.dwFlags = TME_LEAVE | TME_HOVER;// | TME_NONCLIENT
trmouse.dwHoverTime = ;
trmouse.hwndTrack = hwnd;
if(!_TrackMouseEvent(&trmouse))
return FALSE;
if(is_hide) {
not_program_move=false;
MoveWindow(hwnd,, , WIDTH, HEIGHT, FALSE);
is_hide=false;
} else {
if(update_current_group_and_item(hwnd))
InvalidateRect(hwnd,NULL,true);
}
}
break;
case WM_MOUSEWHEEL: { //0x020A
int flag=;
if( (INT)wParam < ) {
int temp=current_top-ITEM_HEIGHT;
if(((groups[current_group].item_num-)/item_columns+)*ITEM_HEIGHT+temp>) {
current_top=temp;
flag=;
}
}
else {
if(current_top<) {//+ITEM_HEIGHT<get_client_height(hwnd)
current_top+=ITEM_HEIGHT;
flag=;
}
}
if(flag)
InvalidateRect( hwnd, NULL, TRUE );
}
break;
case WM_LBUTTONUP: {
int t;
if(get_current_position(hwnd,t)!=-&&t==) {
const char* path= groups[current_group].items[current_item].path.c_str();
const char* arguments= groups[current_group].items[current_item].arguments.c_str();
ShellExecute(NULL, "open",path,arguments, get_directory(path).c_str(), SW_SHOWNORMAL);
InvalidateRect(hwnd,NULL,true);
}
}
break;
case WM_DESTROY:
KillTimer(hwnd,);
PostQuitMessage (); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return ;
}

main.cpp

data.txt的格式如下

                                          //组的个数
常用 //组名称
//组下项目的个数
Chrome //项目名称
C:\chrome\chrome.exe //程序路径
C:\chrome\chrome.exe //图标路径
www.google.com //运行参数
QQ
C:\QQ\bin\QQ.exe
C:\QQ\bin\QQ.exe Everything
C:\everything\everything.exe
C:\everything\everything.exe 网络 迅雷
C:\Thunder\thunder.exe
C:\Thunder\thunder.exe

2017年4月初写

END

上一篇:深入浅出Node.js (4) - 异步编程


下一篇:select控件自动触发change事件