MyRolan

类似 Rolan的快速启动小程序。

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

GitHub地址: MyRolan 。

  1 #if defined(UNICODE) && !defined(_UNICODE)
  2 #define _UNICODE
  3 #elif defined(_UNICODE) && !defined(UNICODE)
  4 #define UNICODE
  5 #endif
  6
  7 #include <tchar.h>
  8 #include <windows.h>
  9 #include <string>
 10 #include <stdio.h>
 11 #include <shellapi.h>
 12 #include <windowsx.h>
 13 #include <commctrl.h>
 14 using namespace std;
 15
 16 /*  Declare Windows procedure  */
 17 LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
 18
 19 /*  Make the class name into a global variable  */
 20 TCHAR szClassName[ ] = _T("MyRolan");
 21
 22 #define GET_X_LPARAM(lp)                        ((int)(short)LOWORD(lp))
 23 #define GET_Y_LPARAM(lp)                        ((int)(short)HIWORD(lp))
 24
 25 typedef struct item {
 26     string name;
 27     string path;
 28     string icon_path;
 29     string arguments;
 30 } item;
 31 typedef struct group {
 32     string name;
 33     item* items;
 34     int item_num;
 35 } group;
 36
 37 int WIDTH=398;
 38 int HEIGHT=500;
 39 int GROUP_WIDTH=100;
 40 int ITEM_WIDTH=100;
 41 int ITEM_HEIGHT=40;
 42 int GROUP_HEIGHT=ITEM_HEIGHT;
 43 #define BKCOLOR    RGB(240,240,240)
 44 #define COMMON_ITEM_BKCOLOR    RGB(220,220,220)
 45 #define ACTIVE_ITEM_BKCOLOR    RGB(200,200,200)
 46
 47
 48 group* groups;
 49 int group_num;
 50 int current_group=0;
 51 int current_item=0;
 52 int current_top=0;
 53 int item_columns=3;
 54
 55
 56
 57 int WINAPI WinMain (HINSTANCE hThisInstance,
 58                     HINSTANCE hPrevInstance,
 59                     LPSTR lpszArgument,
 60                     int nCmdShow)
 61 {
 62     HWND hwnd;               /* This is the handle for our window */
 63     MSG messages;            /* Here messages to the application are saved */
 64     WNDCLASSEX wincl;        /* Data structure for the windowclass */
 65
 66     /* The Window structure */
 67     wincl.hInstance = hThisInstance;
 68     wincl.lpszClassName = szClassName;
 69     wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
 70     wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
 71     wincl.cbSize = sizeof (WNDCLASSEX);
 72
 73     /* Use default icon and mouse-pointer */
 74     wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
 75     wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
 76     wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
 77     wincl.lpszMenuName = NULL;                 /* No menu */
 78     wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
 79     wincl.cbWndExtra = 0;                      /* structure or the window instance */
 80     /* Use Windows‘s default colour as the background of the window */
 81     //wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
 82     wincl.hbrBackground = NULL;
 83     /* Register the window class, and if it fails quit the program */
 84     if (!RegisterClassEx (&wincl))
 85         return 0;
 86
 87     /* The class is registered, let‘s create the program*/
 88     hwnd = CreateWindowEx (
 89                WS_EX_TOOLWINDOW,                   /* Extended possibilites for variation */
 90                szClassName,         /* Classname */
 91                _T("MyRolan"),       /* Title Text */
 92                WS_EX_TOOLWINDOW, /* default window  WS_OVERLAPPEDWINDOW*/
 93                CW_USEDEFAULT,       /* Windows decides the position */
 94                CW_USEDEFAULT,       /* where the window ends up on the screen */
 95                WIDTH,                 /* The programs width */
 96                HEIGHT,                 /* and height in pixels */
 97                HWND_DESKTOP,        /* The window is a child-window to desktop */
 98                NULL,                /* No menu */
 99                hThisInstance,       /* Program Instance handler */
100                NULL                 /* No Window Creation data */
101            );
102     DWORD dwExStyle = GetWindowLong(hwnd, GWL_STYLE);
103     dwExStyle &=~WS_CAPTION;
104     SetWindowLong(hwnd, GWL_STYLE, dwExStyle);
105
106     /* Make the window visible on the screen */
107     ShowWindow (hwnd, nCmdShow);
108
109     /* Run the message loop. It will run until GetMessage() returns 0 */
110     while (GetMessage (&messages, NULL, 0, 0))
111     {
112         /* Translate virtual-key messages into character messages */
113         TranslateMessage(&messages);
114         /* Send message to WindowProcedure */
115         DispatchMessage(&messages);
116     }
117
118     /* The program return-value is 0 - The value that PostQuitMessage() gave */
119     return messages.wParam;
120 }
121 void remove_nextline(char* buf) {
122     int l=strlen(buf);
123     if(buf[l-1]==‘\n‘)
124         buf[l-1]=‘\0‘;
125 }
126 int load_data(HWND hwnd) {
127     FILE* f=fopen("data.txt","r");
128     if(f==NULL) {
129         MessageBox(hwnd,"Data File Not Exist.","Error!",0);
130         return -1;
131     }
132     char buf[500];
133     fgets(buf,500,f);
134     sscanf(buf,"%d",&group_num);
135     groups=new group[group_num];
136     for(int i=0; i<group_num; i++) {
137         fgets(buf,500,f);
138         remove_nextline(buf);
139         groups[i].name=buf;
140         fgets(buf,500,f);
141         sscanf(buf,"%d",&groups[i].item_num);
142         groups[i].items=new item[groups[i].item_num];
143         for(int j=0; j<groups[i].item_num; j++) {
144             fgets(buf,500,f);
145             remove_nextline(buf);
146             groups[i].items[j].name=buf;
147             fgets(buf,500,f);
148             remove_nextline(buf);
149             groups[i].items[j].path=buf;
150             fgets(buf,500,f);
151             remove_nextline(buf);
152             groups[i].items[j].icon_path=buf;
153             fgets(buf,500,f);
154             remove_nextline(buf);
155             groups[i].items[j].arguments=buf;
156         }
157     }
158     fclose(f);
159     return 0;
160 }
161 long get_rect_width(RECT rect) {
162     return rect.right-rect.left;
163 }
164
165 long get_rect_height(RECT rect) {
166     return rect.bottom-rect.top;
167 }
168 long get_client_width(HWND hwnd) {
169     RECT rect;
170     GetClientRect (hwnd, &rect) ;
171     return get_rect_width(rect);
172 }
173
174 long get_client_height(HWND hwnd) {
175     RECT rect;
176     GetClientRect (hwnd, &rect) ;
177     return get_rect_height(rect);
178 }
179 int xy_to_num(int num,int columns,int width,int height,int x,int y) {
180     int c=x/width;
181     if(c>=columns)return -1;
182     int r=y/height;
183     int n=columns*r+c;
184     if(n>=num)return -1;
185     return n;
186 }
187 POINT get_client_mouse(HWND hwnd) {
188     POINT mouse;
189     GetCursorPos(&mouse);//获取鼠标的屏幕坐标
190     ScreenToClient(hwnd,&mouse);//转换为界面坐标
191     return mouse;
192 }
193 int get_current_position(HWND hwnd,int& is_group) {
194     POINT mouse=get_client_mouse(hwnd);
195     if(mouse.x<0||mouse.x>WIDTH||mouse.y<0||mouse.y>HEIGHT)return -1;
196     if(mouse.x<=GROUP_WIDTH) {
197         is_group=1;
198         int n=xy_to_num(group_num,1,GROUP_WIDTH,GROUP_HEIGHT,mouse.x,mouse.y);
199         return n;
200     }
201     is_group=0;
202     int num=groups[current_group].item_num;
203     int n=xy_to_num(num,item_columns,ITEM_WIDTH,ITEM_HEIGHT,mouse.x-GROUP_WIDTH,mouse.y-current_top);
204     return n;
205 }
206 int update_current_group_and_item(HWND hwnd) {
207     int current_group_bak=current_group;
208     int current_item_bak=current_item;
209     int is_group=1;
210     int n=get_current_position(hwnd,is_group);
211     if(n<0)return 0;
212     if(is_group) {
213         current_group=n;
214         current_item=0;
215         current_top=0;
216     }
217     else current_item=n;
218     return (current_group_bak!=current_group)||(current_item_bak!=current_item)?1:0;
219 }
220 void paint_rolan(HWND hwnd,HDC hdc1,HDC hdc) {
221     static HBRUSH  bk_brush =CreateSolidBrush (BKCOLOR);
222     static HBRUSH  common_item_brush =CreateSolidBrush (COMMON_ITEM_BKCOLOR);
223     static HBRUSH  active_item_brush =CreateSolidBrush (ACTIVE_ITEM_BKCOLOR);
224     static HFONT hFont;
225     LOGFONT lf;
226     lf.lfHeight=ITEM_HEIGHT/2.6;
227     lf.lfWidth=0 ;
228     lf.lfEscapement=0 ;
229     lf.lfOrientation=0 ;
230     lf.lfWeight=5;
231     lf.lfItalic=0 ;
232     lf.lfUnderline=0 ;
233     lf.lfStrikeOut=0 ;
234     lf.lfCharSet=DEFAULT_CHARSET ;
235     lf.lfOutPrecision=0 ;
236     lf.lfClipPrecision=0 ;
237     lf.lfQuality=0 ;
238     lf.lfPitchAndFamily=0 ;
239     lstrcpy (lf.lfFaceName, _T("Arial") );
240     PatBlt(hdc, 0, 0, WIDTH,HEIGHT, WHITENESS); //在绘图前调用这个函数可以把背景重画,WHITENESS可以使背景透明
241     hFont = CreateFontIndirect (&lf) ;
242     SelectFont(hdc,hFont);
243     SelectObject (hdc, GetStockObject (NULL_PEN)) ;
244     SelectObject (hdc,bk_brush);
245     Rectangle(hdc,0,0,WIDTH,HEIGHT);
246     for(int i=0; i<group_num; i++) {
247         if(i==current_group) {
248             SelectObject (hdc,active_item_brush);
249             SetBkColor(hdc,ACTIVE_ITEM_BKCOLOR);//设置文字背景色
250         } else {
251             SelectObject (hdc,common_item_brush);
252             SetBkColor(hdc,COMMON_ITEM_BKCOLOR);//设置文字背景色
253         }
254         Rectangle(hdc,0,i*GROUP_HEIGHT-1,GROUP_WIDTH,(i+1)*GROUP_HEIGHT);
255         TextOut(hdc,GROUP_WIDTH/4,i*GROUP_HEIGHT+GROUP_HEIGHT/4,groups[i].name.c_str(),groups[i].name.length());
256     }
257     int gitem_num=groups[current_group].item_num;
258     item* items=groups[current_group].items;
259     int item_num=((gitem_num-1)/item_columns+1)*item_columns;
260     int item_count=0;
261     while(item_count<item_num) {
262         int left=GROUP_WIDTH+(item_count%item_columns)*ITEM_WIDTH;
263         int top=current_top+item_count/item_columns*ITEM_HEIGHT;
264         if(item_count==current_item) {
265             SelectObject (hdc,active_item_brush);
266             SetBkColor(hdc,ACTIVE_ITEM_BKCOLOR);//设置文字背景色
267         } else if(item_count<gitem_num){
268             SelectObject (hdc,common_item_brush);
269             SetBkColor(hdc,COMMON_ITEM_BKCOLOR);//设置文字背景色
270         }else {
271             SelectObject (hdc,bk_brush);
272         }
273         Rectangle(hdc,left-1,top-1,left+ITEM_WIDTH,top+ITEM_HEIGHT);
274         if(item_count<gitem_num)TextOut(hdc,left+ITEM_WIDTH/10,top+ITEM_HEIGHT/4,items[item_count].name.c_str(),items[item_count].name.length());
275         item_count++;
276     }
277     BitBlt(hdc1, 0, 0, WIDTH, HEIGHT, hdc, 0, 0, SRCCOPY); //将位图直接复制在设备上,关于该函数的使用有很多说明,在这里就不再提了
278 }
279 /*  This function is called by the Windows function DispatchMessage()  */
280
281 string get_directory(string path){
282     int last=path.find_last_of(‘\\‘);
283     return path.substr(0,last);
284 }
285
286 LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
287 {
288     static HDC hdc;
289     static PAINTSTRUCT ps ;
290     static bool is_hide;
291     static int screen_height;
292     static bool not_program_move;
293     static HDC hdcBuffer;
294     switch (message) {                /* handle the messages */
295     case WM_CREATE: {
296         not_program_move=true;
297         is_hide=false;
298         screen_height=GetSystemMetrics(SM_CYSCREEN);
299         load_data(hwnd);
300         current_group=0;
301         current_item=0;
302         InvalidateRect(hwnd,NULL,true);
303         SetTimer(hwnd,0,100,NULL);
304         hdc = GetDC(hwnd); //获取设备
305         hdcBuffer = CreateCompatibleDC(hdc); //给设备分配一个内存空间
306         HBITMAP hBitMap = CreateCompatibleBitmap(hdc, WIDTH, HEIGHT); //创建一个cxClient, cyClient大小并且适应DC设备环境的位图
307         ReleaseDC(hwnd, hdc);
308         SelectObject(hdcBuffer, hBitMap); //将位图设置为hdcBuffer的画刷
309     }
310     break;
311     case WM_MOVE: {
312         RECT rect;
313         GetWindowRect(hwnd,&rect);
314         if(not_program_move&&rect.left<=0&&rect.bottom>=screen_height) {
315             not_program_move=false;
316             MoveWindow(hwnd,1-WIDTH,1-HEIGHT, WIDTH, HEIGHT, FALSE);// screen_height-5
317             not_program_move=true;
318         }
319         is_hide=true;
320     }
321     break;
322     case WM_KEYDOWN: { //识别按键
323     }
324     break;
325     case WM_PAINT: {
326         hdc=BeginPaint (hwnd,&ps) ;
327         paint_rolan(hwnd,hdc,hdcBuffer);
328         EndPaint(hwnd,&ps);
329     }
330     break;
331     case WM_TIMER: {
332         RECT rect;
333         GetClientRect(hwnd,&rect);
334         SetWindowPos(hwnd, HWND_TOPMOST, 1, 1, 1, 1,SWP_NOSIZE|SWP_NOMOVE);
335     }
336     break;
337     case WM_MOUSELEAVE: {
338         not_program_move=true;
339         MoveWindow(hwnd,1-WIDTH,1-HEIGHT, WIDTH, HEIGHT, FALSE);// screen_height-5
340         is_hide=true;
341     }
342     break;
343     case WM_MOUSEHOVER:
344         break;
345     case WM_MOUSEMOVE: {
346         TRACKMOUSEEVENT trmouse;
347         trmouse.cbSize = sizeof(TRACKMOUSEEVENT);
348         trmouse.dwFlags = TME_LEAVE | TME_HOVER;// | TME_NONCLIENT
349         trmouse.dwHoverTime = 2000;
350         trmouse.hwndTrack = hwnd;
351         if(!_TrackMouseEvent(&trmouse))
352             return FALSE;
353         if(is_hide) {
354             not_program_move=false;
355             MoveWindow(hwnd,0, 0, WIDTH, HEIGHT, FALSE);
356             is_hide=false;
357         } else {
358             if(update_current_group_and_item(hwnd))
359                 InvalidateRect(hwnd,NULL,true);
360         }
361     }
362     break;
363     case WM_MOUSEWHEEL: { //0x020A
364         int flag=0;
365         if( (INT)wParam < 0 ) {
366             int temp=current_top-ITEM_HEIGHT;
367             if(((groups[current_group].item_num-1)/item_columns+1)*ITEM_HEIGHT+temp>0) {
368                 current_top=temp;
369                 flag=1;
370             }
371         }
372         else {
373             if(current_top<0) {//+ITEM_HEIGHT<get_client_height(hwnd)
374                 current_top+=ITEM_HEIGHT;
375                 flag=1;
376             }
377         }
378         if(flag)
379             InvalidateRect( hwnd, NULL, TRUE );
380     }
381     break;
382     case WM_LBUTTONUP: {
383         int t;
384         if(get_current_position(hwnd,t)!=-1&&t==0) {
385             const char* path= groups[current_group].items[current_item].path.c_str();
386             const char* arguments= groups[current_group].items[current_item].arguments.c_str();
387             ShellExecute(NULL, "open",path,arguments, get_directory(path).c_str(), SW_SHOWNORMAL);
388             InvalidateRect(hwnd,NULL,true);
389         }
390     }
391     break;
392     case WM_DESTROY:
393         KillTimer(hwnd,0);
394         PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
395         break;
396     default:                      /* for messages that we don‘t deal with */
397         return DefWindowProc (hwnd, message, wParam, lParam);
398     }
399     return 0;
400 }

main.cpp

data.txt的格式如下

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

2017年4月初写

END

时间: 2024-10-12 09:45:14

MyRolan的相关文章