|  | 
 
| GpTerm是一个运行在文曲星(Golden Global View)的GP1288 LinuxPDA上的虚拟终端程序,原作者为honeycombs,原版本为3.01 
 我将代码按自己的需要修改了一些,也加上注释(可能某些注释有问题),这些放在硬盘上有段时间了(这部分是放在公司电脑上的,也忘记是否是最新版本了),翻出来贴上这里,当作备份也好,说不定对某些朋友有帮助(附件里有完整的代码包,可以用GP1288的WD编译器编译成GP1288用的安装程序)
 
 程序所用的API为macrowin的win32 like API,挺像win32 API,很好玩
 
 [code:1]
 /*
 * Copyright (c) 1999 Greg Haerr <[email protected]>
 *
 * Microwindows Terminal Emulator for Linux
 *
 * Yes, this is just a demo, and doesn't repaint contents on refresh.
 */
 
 /*20031219,开始看代码,尝试实现在执行命令输出信息时自动最小化软键盘以便
 扩大输出信息的可视方便输出信息阅读,失败,因为listbox在程序运行时扩大后
 无法刷新扩大的显示区域,有残影,即使ResetScreen也无法解决问题,相同的代码,
 换成使用edittxt控件则完全没问题,但使用edittxt需要修改不少代码,而且效果
 也不是很好;苦想中...*/
 /*20031220,小改动,在软键盘还原时自动将焦点落在命令输入框,方便输入命令*/
 /*20031221,小改动,每次执行命令输出信息时不再清listbox,而是连续输出,并将
 listbox框的100行限制调整到500*/
 /*20031222,终于解决listbox框残影问题,方法是先建立大的listbox,那么即使变小
 再变大也不会有残影*/
 /*20031222,看菜单范例程序,开始尝试建立菜单,解决原程序里只要点击窗口标题栏程
 序(呼出菜单——虽然没有菜单)崩溃的问题*/
 /*20031222,加入?按钮,原意是用来显示“关于”信息,但showabout失败,何解???*/
 /*20031222,解决X和?按钮在listbox变化时自动隐藏的问题,使用resetscreen刷新*/
 /*20031223,参考了kuthb和kuword的源码后,终于成功showabout和showhelp,将版本号改成3.10*/
 /*20031223,完善了帮助信息,扩充?按钮的帮助功能*/
 /*20031224,开始增加热键功能,将home键定义为输入“/”(“/”符号最常使用),end键定义为回车执行命令*/
 /*20031225,订正了在显示帮助信息、关于信息和命令执行信息时home和end热键仍然起作用的小BUG*/
 /*20031229,加入设置菜单“自动滚屏”和“最大化”,更多的自定义设置,力图满足各种用户习惯*/
 /*20031229,焦点落在信息框时能使用滚轮翻页,版本号改为3.11*/
 /*20031229,记录屏幕功能开始工作,正常*/
 /*20031229,热键设置功能实现,工作正常,版本号升为3.14*/
 /*20031229,ESC键切换输入法最大最小化状态,方便用户操作*/
 /*20031230,无意中发现实现令程序执行UID为100的方法,狂喜中,当程序的UID为100时,能摆脱很多权限限制...*/
 /*20031230,工作繁忙,搞了几乎一天,累,晚上不看程序只看电视,轻松一下*/
 /*20031231,开始苦苦冥想和尝试各种企图让程序UID为0也就是root权限的方法,到2004.1.1凌晨4点均告失败*/
 /*20040101,睡到11:30才起床,饭堂竟然没开工,只好泡面吃,继续尝试,root权限实在让人向往*/
 /*20040101下午4点多,终于通过间接的方法实现了程序以root身份执行,方法是...嘿嘿,这可不能告诉你!现在GpTerm
 上可以干任何喜欢干的事情了,包括格式化系统:-),版本号升为3.141*/
 /*20040101,再接再励,将删除log文件功能实现,增加查看log功能,现在不用联接电脑也能viewlog啦*/
 /*20040101,整理了一下乱七八糟的代码,吃饭去啦*/
 /*20040104,玩了几天,继续改代码,现在可以保存的设置项更多了,设置菜单里的所有设置都能保存*/
 /*20040104,在信息框最大化时,按一下END键能立即切换到命令输入状态,便于输入命令*/
 /*20040104,整理代码,将读取设置和保存设置独立成函数,方便代码的阅读*/
 /*20040105,加入粘贴功能,可以将一些较长的命令先复制起来反复粘贴*/
 /*  20040109,加入复制功能,整理一下代码 */
 /* 20040110,完善复制粘贴功能,增加“全选”功能,并改善四个方向热键功能 */
 /* 20040117,参看记录文件对话框实现滚轮和上下键翻页,方便查看 */
 /* 20040117,在设置热键对话框增加一个恢复缺省设置的按钮 */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
 #include <signal.h>
 #define MWINCLUDECOLORS
 #include "windows.h"
 #include "wintern.h"                /* for MwRegisterFdInput*/
 #include "wintools.h"                /* Draw3dInset*/
 #include "xime.h"
 #include "../pubuse/gobalfun.h"
 #include "rc.h"
 #include <sys/stat.h>
 
 #define FGCOLOR                BLACK
 #define BKCOLOR                WHITE
 #define FONTNAME        SYSTEM_FIXED_FONT
 
 #define APPCLASS        "GpTerm 3.141"
 
 #if DOS_DJGPP
 #define killpg                kill
 #define SIGCHLD                17 /* from Linux, not defined in DJGPP */
 #endif
 
 #ifdef __uClinux__
 #define killpg(x,y) kill(-x,y)
 #endif
 
 /* forward decls*/
 
 extern menu_info[];
 extern dialog_info[];
 
 extern int WINAPI RegisterAboutClass( HINSTANCE hInstance );
 extern int WINAPI RegisterHelpClass( HINSTANCE hInstance );
 extern int enable_getting_pda_key;
 
 extern LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wp,LPARAM lp);//主窗口过程
 extern LRESULT CALLBACK set_dlg_proc(HWND hwnd,UINT uMsg,WPARAM wp,LPARAM lp);//热键设置对话框过程
 extern LRESULT CALLBACK viewlog_dlg_proc(HWND hwnd,UINT uMsg,WPARAM wp,LPARAM lp);//查看LOG对话框过程
 
 void EmOutChar(HWND hwnd, int ch);
 int  CreatePtyShell(void);
 int  ReadPtyShell(int fd, char *buf, int count);
 int  WritePtyShell(int fd, char *buf, int count);
 void ClosePtyShell(int fd);
 
 
 /* local data*/
 static int ttyfd = -1;
 
 int RegisterAppClass(void)
 {
 WNDCLASS        wc;
 
 wc.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
 wc.lpfnWndProc = (WNDPROC)WndProc;
 wc.cbClsExtra = 0;
 wc.cbWndExtra = 0;
 wc.hInstance = 0;
 wc.hIcon = 0; /*LoadIcon(GetHInstance(), MAKEINTRESOURCE( 1));*/
 wc.hCursor = 0; /*LoadCursor(NULL, IDC_ARROW);*/
 wc.hbrBackground = CreateSolidBrush(BKCOLOR);
 wc.lpszMenuName ="term_menu";
 wc.lpszClassName =  APPCLASS;
 RegisterClass( &wc);
 return 1;
 }
 
 HWND CreateAppWindow(void)
 {
 HWND        hwnd;
 hwnd = CreateWindowEx(0L, APPCLASS,
 APPCLASS,
 WS_OVERLAPPEDWINDOW | WS_VISIBLE,
 0, 0,
 160, 240,
 NULL, (HMENU)LoadMenuEx(menu_info,"term_menu",24), NULL, NULL);
 //NULL, (HMENU)1, NULL, NULL);//原程序里作者这里的(HMENU)1会造成呼出菜单时程序崩溃,因为1太小
 SetDefaultSwitchWindow( hwnd );
 SetDefaultKeyWindow(hwnd);//设置缺省的按键响应窗口,这样当焦点即使落在命令输入框时按panelkey消息还是发给窗口而不是控件本身
 OpenClipboard(hwnd);//打开剪贴板
 return hwnd;
 }
 
 HWND hWndIme ;
 
 #define IDS_MESSAGE (WM_USER+2001)
 #define IDB_SEND    (WM_USER+2002)
 #define IDB_EXIT    (WM_USER+2003)
 #define IDE_CMD     (WM_USER+2004)
 #define IDB_HELP   (WM_USER+2005)
 
 USER_LISTBOX lst_stdout = {0,IDS_MESSAGE,WS_HSCROLL};
 USER_BUTTON  btn_Run    = {0,IDB_SEND   , BS_PUSHBUTTON  ,"Run\0"};
 USER_BUTTON btn_Exit   =  {0,IDB_EXIT , BS_PUSHBUTTON  ,"X\0"};
 USER_EDIT edit_cmd      = {0,IDE_CMD ,WS_BORDER};
 USER_BUTTON btn_Help        =  {0,IDB_HELP , BS_PUSHBUTTON  ,"?\0"};
 
 
 int WndProc_OnCreate(HWND hWnd)
 {
 ttyfd = CreatePtyShell();
 if(ttyfd == -1)
 return -1;
 MwRegisterFdInput(hWnd, ttyfd);
 }
 
 int WndProc_OnDestory(HWND hWnd)
 {
 DestroyXime();//先销毁输入法
 if (save_ini()!=1)
 MessageBox(NULL,"不好意思!\n出错啦!\n请检查磁盘空间是否不足!","保存设置文件失败!",MB_OK|MB_ICONSTOP);//保存当前设置
 CloseClipboard ();//关闭剪贴板
 if(ttyfd>0)
 {
 MwUnregisterFdInput(hWnd, ttyfd);
 ClosePtyShell(ttyfd);
 ttyfd=0;
 }//注销窗口和终端的关联并关闭终端的进程
 PostQuitMessage(0);//退出
 }
 
 static int autoscroll=0;
 static int listboxmax=1;
 static int autocls=0;
 static char LOG_FileName[180];
 static char INI_FileName[180];
 char keyup_define[100];
 char keydown_define[100];
 char keyleft_define[100];
 char keyright_define[100];
 
 FILE *fp_log;
 
 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
 HWND hlistbox;
 HWND hedit;
 HWND hbtn_run;
 int i=0;
 char listbox_string[1024];
 char buf[100];
 char search_text[10];
 long j;
 
 /* PAINTSTRUCT ps;
 HDC hdc; */
 
 switch(msg) {
 case WM_CREATE:
 {
 LPCREATESTRUCT lpCreateStruct=(LPCREATESTRUCT)lParam;
 CreatButton(hwnd,&btn_Exit,lpCreateStruct->hInstance,145,1,14,14);
 //CreatListBox(hwnd,&lst_stdout,lpCreateStruct->hInstance,0,15,160,105);
 CreatListBox(hwnd,&lst_stdout,lpCreateStruct->hInstance,0, 15, 160, 225);//默认建立全屏的listbox,避免由小listbox变成大listbox的无法刷新现象
 CreatEdit(hwnd,&edit_cmd,lpCreateStruct->hInstance,0,122,120,18);
 CreatButton(hwnd,&btn_Run,lpCreateStruct->hInstance,122,122,38,18);
 CreatButton(hwnd,&btn_Help,lpCreateStruct->hInstance,130,1,14,14);
 
 ShowWindow(edit_cmd.hWnd,SW_HIDE);
 ShowWindow(btn_Run.hWnd,SW_HIDE);
 
 ListBox_InsertString(lst_stdout.hWnd,0,"欢迎使用GpTerm!!!");
 ListBox_InsertString(lst_stdout.hWnd,1,"点击右下角的小图标开始!");
 
 hWndIme =initXime(hwnd, XIME_NONE);
 EnableXimeMinimize (TRUE);//输入法允许最小化
 
 if (listboxmax==1) CheckMenuItem(hwnd->hMenu,ID_MAX,MF_CHECKED);//这三行为初始化设置菜单的状态
 if (autoscroll==1) CheckMenuItem(hwnd->hMenu,ID_AUTOSCROLL,MF_CHECKED);
 if (autocls==1) CheckMenuItem(hwnd->hMenu,ID_AUTOCLS,MF_CHECKED);
 
 WndProc_OnCreate(hwnd);
 
 if ((getuid())==0)
 {
 SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)(LPSTR)"GpTerm(root模式)");//如果uid为0,即为root模式,将窗口的标题栏加上指示字样
 EnableMenuItem(hwnd->hMenu,ID_ROOT,MF_GRAYED);//菜单“切换...”变灰不能选
 }
 
 }break;
 /* case WM_PAINT:
 hdc = BeginPaint( hwnd, &ps );
 UpdateWindow(btn_Help.hWnd);
 EndPaint( hwnd, &ps );
 break; */
 case WM_XIME_MINIMIZE: //输入法最小化时的动作
 {
 ShowWindow(edit_cmd.hWnd,SW_HIDE);
 ShowWindow(btn_Run.hWnd,SW_HIDE);
 MoveWindow(lst_stdout.hWnd, 0, 15, 160, 225, 1);
 SendMessage (lst_stdout.hWnd, WM_PAINT, 0, 0);
 SetFocus(lst_stdout.hWnd);//输出信息时焦点自动落在listbox框以便用滚轮翻页
 ResetScreen();                                  //刷新整个窗口
 }break;
 case WM_XIME_RESTORE: //输入法恢复时的动作
 {
 MoveWindow(lst_stdout.hWnd, 0, 15, 160, 105, 1);
 ShowWindow(btn_Run.hWnd,SW_SHOW);
 ShowWindow(edit_cmd.hWnd,SW_SHOW);
 SendMessage (lst_stdout.hWnd, WM_PAINT, 0, 0);
 SetFocus(edit_cmd.hWnd);//恢复输入法后默认焦点落在命令输入框上以便输入命令
 ResetScreen();     //刷新整个窗口
 }break;
 case WM_COMMAND://处理各种命令消息
 {
 if(LOWORD(wParam)==btn_Run.nID)//如果按下“run”按钮
 {
 if(ttyfd >0)
 {
 char cmdmsg[128];
 int cmdlen=0;
 Edit_GetText(edit_cmd.hWnd,cmdmsg,127);
 Edit_SetText(edit_cmd.hWnd,"");
 strcat(cmdmsg,"\n");
 cmdlen=strlen(cmdmsg);
 if(cmdlen>0)
 {
 if (listboxmax==1) SelectXime(XIME_NONE);//最小化输入法以增大输出信息的可视区域
 if (autocls==1) ListBox_ResetContent(lst_stdout.hWnd); //取消这行则不清listbox
 WritePtyShell(ttyfd,cmdmsg,cmdlen);
 }
 }
 
 }
 else if(LOWORD(wParam)==btn_Exit.nID||LOWORD(wParam)==ID_QUIT)//如果按下关闭按钮或“退出”菜单
 {
 //ListBox_ResetContent(lst_stdout.hWnd);
 WndProc_OnDestory(hwnd);
 }
 else if(LOWORD(wParam)==ID_ABOUT)//如果点击“关于”菜单
 {
 showabout("GpTerm");
 }
 else if(LOWORD(wParam)==ID_CLR)//如果点击“清屏”菜单
 {
 ListBox_ResetContent(lst_stdout.hWnd);//清listbox
 }
 else if(LOWORD(wParam)==btn_Help.nID)//如果点击?按钮
 {
 if((GetSelectedIME()==XIME_NONE)) showhelp("GpTerm","min");
 else showhelp("GpTerm","max");//输入状态
 }
 else if(LOWORD(wParam)==ID_HELP)//如果点击“帮助”菜单
 {
 showhelp("GpTerm","main");
 }
 else if(LOWORD(wParam)==ID_AUTOSCROLL)//如果点击“自动滚动”菜单
 {
 if (autoscroll==0)
 {
 CheckMenuItem(hwnd->hMenu,ID_AUTOSCROLL,MF_CHECKED);
 autoscroll=1;
 }
 else
 {
 CheckMenuItem(hwnd->hMenu,ID_AUTOSCROLL,MF_UNCHECKED);
 autoscroll=0;
 }
 }
 else if(LOWORD(wParam)==ID_MAX)//如果点击“屏幕最大化”菜单
 {
 if (listboxmax==0)
 {
 CheckMenuItem(hwnd->hMenu,ID_MAX,MF_CHECKED);
 listboxmax=1;
 }
 else
 {
 CheckMenuItem(hwnd->hMenu,ID_MAX,MF_UNCHECKED);
 listboxmax=0;
 }
 }
 else if(LOWORD(wParam)==ID_AUTOCLS)//如果点击“自动清屏”菜单
 {
 if (autocls==0)
 {
 CheckMenuItem(hwnd->hMenu,ID_AUTOCLS,MF_CHECKED);
 autocls=1;
 }
 else
 {
 CheckMenuItem(hwnd->hMenu,ID_AUTOCLS,MF_UNCHECKED);
 autocls=0;
 }
 }
 else if(LOWORD(wParam)==ID_LOG)//如果点击“记录屏幕”菜单
 {
 fp_log=fopen(LOG_FileName,"a");//以追加方式打开log文件
 if (fp_log!=NULL)
 {
 for (i=0;i<ListBox_GetCount(lst_stdout.hWnd);i++)
 {
 SendMessage(lst_stdout.hWnd,LB_GETTEXT,i,(LPARAM)(LPSTR)listbox_string);
 strcat(listbox_string,"\n");
 fputs(listbox_string,fp_log);//将listbox框内容全部写进log文件里
 }
 get_ymdhms(listbox_string);
 strcat(listbox_string,"时刻记录!\n\n\n");
 fputs(listbox_string,fp_log);//加上当前日期时刻标志
 fclose(fp_log);//关闭log文件
 }
 else MessageBox(NULL,"不好意思!\n出错啦!\n请检查磁盘空间是否不足\n并\n清除记录文件\0","打开记录文件出错!",MB_OK|MB_ICONSTOP);
 }
 else if(LOWORD(wParam)==ID_DELLOG)//如果点击“删除记录文件”菜单
 {
 remove(LOG_FileName);
 }
 else if(LOWORD(wParam)==ID_SET)//如果点击“热键设置”菜单
 {
 DialogBoxEx( NULL, "SET_DLG", hwnd, set_dlg_proc,dialog_info, 10 );//显示“热键设置”对话框进行热键设置
 }
 else if(LOWORD(wParam)==ID_ROOT)//如果点击“切换成root模式”菜单,嘿嘿...
 {
 
 }
 else if(LOWORD(wParam)==ID_VIEWLOG)//如果点击“查看记录”菜单
 {
 DialogBoxEx( NULL, "VIEWLOG_DLG", hwnd,viewlog_dlg_proc,dialog_info, 2 );//显示“查看记录”对话框
 }
 else if(LOWORD(wParam)==ID_PASTE)//如果点击“粘贴”菜单
 {
 if (ReadClipboard (buf, GetClipboardSize()))//读取系统剪贴板内容
 {
 insert_string(edit_cmd.hWnd,buf);//将内容粘贴出来
 }
 else MessageBox(NULL,"粘贴操作出错!","错误!",0);
 }
 else if(LOWORD(wParam)==ID_COPY)//如果点击“复制”菜单
 {
 SendMessage(edit_cmd.hWnd,EM_GETSELTEXT,100,(LPARAM)(LPSTR)buf);//将edit控件里反黑选择的内容读到buf
 if (WriteClipboard(buf)!=1) MessageBox(NULL,"复制操作出错!","错误!",0);//将buf写入系统剪贴板
 }
 else if(LOWORD(wParam)==ID_SELALL)//如果点击“全选”菜单
 {
 SendMessage(edit_cmd.hWnd,EM_SETSEL,0,SendMessage(edit_cmd.hWnd,WM_GETTEXTLENGTH,0,0));//将edit控件里的内容全选
 }
 /* else if(LOWORD(wParam)==ID_SEARCH)
 {
 InputBox(search_text,10,"ha\0","haha\0",FALSE);
 }  */
 }break;
 case WM_KEYDOWN://处理各种按键按下消息
 {
 switch (LOWORD(wParam))
 {
 case VK_HOME://如果按下“home”键
 if (GetFocus()==edit_cmd.hWnd)
 {
 SendMessage(edit_cmd.hWnd,WM_CHAR,'/',0);//在edit控件插入“/”字符
 }
 break;
 case VK_END://如果按下“end”键
 if (GetFocus()==edit_cmd.hWnd)//如果焦点落在edit控件上则
 {
 SendMessage(hwnd,WM_COMMAND,btn_Run.nID,0);//发送“run”按钮按下的消息,相当于“run”按钮被按下
 }
 else SendMessage(hwnd,WM_KEYDOWN,VK_ESCAPE,0);//发送“esc”按钮按下消息,相当于“esc”键被按下
 break;
 case VK_NEXT://如果按下滚轮的下键
 if(GetFocus()==lst_stdout.hWnd)//如果焦点落在listbox框,则
 {
 SendMessage(lst_stdout.hWnd,WM_VSCROLL,SB_PAGEDOWN,0);//滚轮翻页处理
 //SendMessage(lst_stdout.hWnd,WM_KEYDOWN,VK_END,0);
 }
 break;
 case VK_PRIOR://如果按下滚路的上键
 if(GetFocus()==lst_stdout.hWnd)
 {
 SendMessage(lst_stdout.hWnd,WM_VSCROLL,SB_PAGEUP,0);
 }
 break;
 case VK_UP://如果按下上键
 if (GetFocus()==edit_cmd.hWnd)//如果焦点在edit控件上,则
 {
 insert_string(edit_cmd.hWnd,keyup_define);//插入自定义的上键字符串
 }
 break;
 case VK_DOWN://如果按下下键
 if (GetFocus()==edit_cmd.hWnd)
 {
 insert_string(edit_cmd.hWnd,keydown_define);
 }
 break;
 case VK_LEFT://如果按下左键
 if (GetFocus()==edit_cmd.hWnd)
 {
 insert_string(edit_cmd.hWnd,keyleft_define);
 }
 break;
 case VK_RIGHT://如果按下右键
 if (GetFocus()==edit_cmd.hWnd)
 {
 insert_string(edit_cmd.hWnd,keyright_define);
 }
 break;
 case VK_ESCAPE://如果按下“esc”键,则切换输入法状态
 if((GetSelectedIME()==XIME_NONE)) SelectXime(XIME_DEFAULT);
 else SelectXime(XIME_NONE);//切换输入法状态
 break;
 }
 }break;
 
 case WM_FDINPUT://处理终端进程消息
 {
 unsigned char ch;
 if(ReadPtyShell(ttyfd, &ch, 1) == 1)//读取终端管道输出的1个字符
 {
 EmOutChar(hwnd, ch);
 }
 }break;
 //有些朋友可能觉得奇怪,上面的处理为何要逐个字符读取而不全部一次性将管道输出全部读取呢,这样效率不是高很多吗?!
 //这是因为管道输出的信息里有tab符,回车换行符,退格符,响铃符这些特殊符号,而listbox框显示这些时不会处理这些特殊符
 //因此得逐个读取字符,当读取到这些特殊字符时EmOutChar函数按这些符号的真正意义将字符串格式化,然后再送往listbox框显示
 //但如果用edit控件代替listbox控件,可以一次性全部读取再显示,因为edit控件能自动处理这些特殊符号
 //那为什么又不用edit控件代替listbox控件来显示呢,何况edit控件调整大小时不会留下残影
 //呵呵,原因有三:
 //一、我比较懒,既然原作者使用了listbox控件,我就不想换了,否则自己还要修改部分代码,多麻烦呀:-)
 //二、如果使用了edit控件,由于它不支持插入整个字符串,那么就意味着要显示的内容必须一次性显示,也就是说屏幕显示不会滚动了,失去动感,这样的(个人)感觉太差了
 //三、如果使用了edit控件,由于它不支持删掉其中一行字符串的操作,这就意味着随着执行命令越多,屏幕输出信息越多,保存屏幕输出信息的字符串变量就越大,容易造成程序崩溃
 //由于以上三个原因,我还是支持原作者的做法,使用listbox控件显示,listbox控件可以逐条加入信息,可以删除一条信息,和实际的终端输出动作很相似
 //当然,你可以试试为edit控件插入一行字符串的函数,写删除其中一行字符串的函数,再用edit控件来显示...
 //如果你真实现了,别忘记通知我和原作者,让我们分享一下你成功的乐趣:->
 
 default:
 return DefWindowProc(hwnd, msg, wParam, lParam);//缺省的处理消息过程
 }
 return 0;
 }
 
 HWND OldXimeOwner;
 InputMethod OldIME;
 
 LRESULT CALLBACK set_dlg_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
 switch ( msg )
 {
 case WM_INITDIALOG:
 SendMessage(GetDlgItem(hwnd,EDIT_UP),WM_SETTEXT,0,(LPARAM)(LPSTR)keyup_define);//显示自定义的热键设置
 SendMessage(GetDlgItem(hwnd,EDIT_DOWN),WM_SETTEXT,0,(LPARAM)(LPSTR)keydown_define);
 SendMessage(GetDlgItem(hwnd,EDIT_LEFT),WM_SETTEXT,0,(LPARAM)(LPSTR)keyleft_define);
 SendMessage(GetDlgItem(hwnd,EDIT_RIGHT),WM_SETTEXT,0,(LPARAM)(LPSTR)keyright_define);
 SetFocus(GetDlgItem(hwnd,EDIT_UP));//焦点自动落在上键的输入框上
 OldXimeOwner=SetXimeOwner(hwnd);//保存原先的输入法句柄
 OldIME=GetSelectedIME();//保存主窗口输入法状态
 SelectXime(XIME_ASCII);        //切换输入法到英数输入
 break;
 case WM_COMMAND:
 switch (LOWORD( wParam ))
 {
 case BTN_DLG_CANCEL://如果按下“取消”按钮
 SetXimeOwner(OldXimeOwner);//恢复输入法到主窗口
 SelectXime(OldIME);//恢复主窗口的输入法
 EndDialog(hwnd,TRUE);//结束“热键设置”对话框
 break;
 case BTN_DLG_OK://如果按下“确定”按钮
 SendMessage(GetDlgItem(hwnd,EDIT_UP),WM_GETTEXT,100,(LPARAM)(LPSTR)keyup_define);//读取新的热键设置
 SendMessage(GetDlgItem(hwnd,EDIT_DOWN),WM_GETTEXT,100,(LPARAM)(LPSTR)keydown_define);
 SendMessage(GetDlgItem(hwnd,EDIT_LEFT),WM_GETTEXT,100,(LPARAM)(LPSTR)keyleft_define);
 SendMessage(GetDlgItem(hwnd,EDIT_RIGHT),WM_GETTEXT,100,(LPARAM)(LPSTR)keyright_define);
 SetXimeOwner(OldXimeOwner);
 SelectXime(OldIME);
 EndDialog(hwnd,TRUE);
 break;
 case BTN_DLG_DEFAULT:
 SendMessage(GetDlgItem(hwnd,EDIT_UP),WM_SETTEXT,0,(LPARAM)(LPSTR)"cd");//设置缺省的热键设置
 SendMessage(GetDlgItem(hwnd,EDIT_DOWN),WM_SETTEXT,0,(LPARAM)(LPSTR)"cp");
 SendMessage(GetDlgItem(hwnd,EDIT_LEFT),WM_SETTEXT,0,(LPARAM)(LPSTR)"rm");
 SendMessage(GetDlgItem(hwnd,EDIT_RIGHT),WM_SETTEXT,0,(LPARAM)(LPSTR)"ls");
 break;
 }
 break;
 default:
 return DefWindowProc( hwnd, msg, wParam, lParam );
 }
 return 0;
 }
 
 LRESULT CALLBACK viewlog_dlg_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
 switch ( msg )
 {
 case WM_INITDIALOG:
 OldXimeOwner=GetDefaultKeyWindow();//保存好原来的缺省按键响应窗口句柄
 SetDefaultKeyWindow(hwnd);//将缺省的按键相应窗口设置为当前此对话框以便进行滚轮翻页
 ReadFile(LOG_FileName,GetDlgItem(hwnd,LOGTXT));//读取log文件内容并显示
 SetFocus(GetDlgItem(hwnd,LOGTXT));//设置焦点
 break;
 case WM_COMMAND:
 switch (LOWORD( wParam ))
 {
 case BTN_VIEWLOG_OK:
 SetDefaultKeyWindow(OldXimeOwner);//恢复缺省的按键响应窗口
 EndDialog(hwnd,TRUE);//退出对话框
 break;
 }
 break;
 case WM_KEYDOWN:
 switch (LOWORD( wParam ))
 {
 case VK_DOWN:
 case VK_NEXT:
 SendMessage(GetDlgItem(hwnd,LOGTXT), WM_VSCROLL , SB_PAGEDOWN,0);//滚轮翻页处理
 break;
 case VK_UP:
 case VK_PRIOR:
 SendMessage(GetDlgItem(hwnd,LOGTXT), WM_VSCROLL , SB_PAGEUP,0);
 break;
 }
 break;
 default:
 return DefWindowProc( hwnd, msg, wParam, lParam );
 }
 
 }
 
 
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
 int nShowCmd)
 {
 MSG         msg;
 
 sprintf ((char*)(LOG_FileName), "%s/data/%s/%s",getenv ("PDAROOT"), "GpTerm","GpTerm_Log.txt\0");//获得log文件的绝对路径
 sprintf ((char*)(INI_FileName), "%s/data/%s/%s",getenv ("PDAROOT"), "GpTerm","GpTerm.ini\0");//获得ini文件的绝对路径
 
 RegisterAppClass();//注册窗口的类
 
 if (load_ini()!=1) //读取ini设置文件
 {
 MessageBox(NULL,"不好意思!\n出错啦!\n可能设置文件有错误,\n已恢复成缺省设置!","打开设置文件失败!",MB_OK|MB_ICONINFORMATION);
 strcpy(keyup_define,"cd \n");//恢复缺省设置
 strcpy(keydown_define,"ls \n");
 strcpy(keyleft_define,"rm \n");
 strcpy(keyright_define,"cp \n");
 listboxmax=1;
 autoscroll=0;
 autocls=1;
 }
 
 CreateAppWindow();//创建并显示主窗口
 
 enable_getting_pda_key=1;//使用热键
 
 RegisterAboutClass(hInstance);//注册“关于”信息
 RegisterHelpClass(hInstance);//注册“帮助”信息
 
 while(GetMessage(&msg, NULL, 0, 0))
 {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
 }
 
 return 0;
 }
 
 static char listlinemsg[1024];
 static int listlinenum=0;
 
 void EmOutChar(HWND hwnd, int ch)
 {
 if(ttyfd<=0)
 return ;
 
 switch(ch) {
 case '\r':
 {
 }return;
 case '\n'://处理换行符
 {
 if(listlinenum>0)
 {
 int linelen=0;
 while((linelen=ListBox_GetCount(lst_stdout.hWnd))>500)
 ListBox_DeleteString(lst_stdout.hWnd,0);
 if(linelen<0)linelen=0;
 listlinemsg[listlinenum]=0;
 ListBox_InsertString(lst_stdout.hWnd,linelen,listlinemsg);
 //SendMessage(lst_stdout.hWnd,WM_KEYDOWN,VK_END,0);
 if (autoscroll==1) SendMessage(lst_stdout.hWnd,WM_VSCROLL,SB_LINEDOWN,0);//如果设置了自动滚屏则滚屏
 listlinenum=0;
 listlinemsg[0]=0;
 }
 }return;
 case '\007':                        /* bel*/
 {
 write(STDERR_FILENO, "\007", 1);
 }return;
 case '\t'://处理tab符
 {
 listlinemsg[listlinenum++]=' ';
 listlinemsg[listlinenum++]=' ';
 listlinemsg[listlinenum++]=' ';
 listlinemsg[listlinenum++]=' ';
 listlinemsg[listlinenum]=0;
 }return;
 case '\b'://处理退格符
 {
 if(listlinenum>0)
 listlinenum--;
 listlinemsg[listlinenum]=0;
 }return;
 default:
 {
 listlinemsg[listlinenum++]=ch;
 listlinemsg[listlinenum]=0;
 }
 }
 }
 
 
 
 
 
 
 
 
 
 
 
 #if ELKS
 #define SHELL        "/bin/sash"
 #else
 #if DOS_DJGPP
 #define SHELL        "bash"
 #else
 #define SHELL        "/bin/sh"
 #endif
 #endif
 
 static int pid=0;
 
 static void ptysignaled(int signo)
 {
 switch(signo) {
 case SIGINT:        /* interrupt*/
 #if !ELKS
 /* this doesn't work, can anyone fix it?*/
 killpg(pid, SIGINT);
 #endif
 return;
 case SIGCHLD:        /* child status change - child exit*/
 DestroyWindow(GetActiveWindow());
 CreateAppWindow();
 return;
 }
 fprintf(stderr, "Uncaught signal %d\n", signo);
 }
 
 /*
 * Create a shell running through a pseudo tty, return the shell fd.
 */
 int CreatePtyShell(void)
 {
 int        n = 0;
 int        tfd;
 char        pty_name[40];
 char *        argv[2];
 
 while(1){
 sprintf(pty_name, "/dev/ptyp%d", n);
 n++;
 if ((tfd = open(pty_name, O_RDWR | O_NONBLOCK)) <= 0)
 {
 if ((errno == EBUSY || errno == EIO) && n < 10)
 continue;
 fprintf(stderr, "Can't create pty %s\n", pty_name);
 return -1;
 }
 else break;
 }
 signal(SIGCHLD, ptysignaled);
 signal(SIGINT, ptysignaled);
 #ifdef __uClinux__
 #undef fork
 #define fork() vfork()
 #endif
 if ((pid = fork()) == -1) {
 fprintf(stderr, "No processes\n");
 return -1;
 }
 if (!pid) {
 close(STDIN_FILENO);
 close(STDOUT_FILENO);
 close(STDERR_FILENO);
 close(tfd);
 
 setsid();
 pty_name[5] = 't';
 if ((tfd = open(pty_name, O_RDWR)) < 0) {
 fprintf(stderr, "Child: Can't open pty %s\n", pty_name);
 exit(1);
 }
 dup2(tfd, STDIN_FILENO);
 dup2(tfd, STDOUT_FILENO);
 dup2(tfd, STDERR_FILENO);
 /*if(!(argv[0] = getenv("SHELL")))*/
 argv[0] = SHELL;
 argv[1] = NULL;
 execv(argv[0], argv);
 exit(1);
 }
 return tfd;
 }
 
 int ReadPtyShell(int fd, char *buf, int count)
 {
 return read(fd, buf, count);
 }
 
 int WritePtyShell(int fd, char *buf, int count)
 {
 return write(fd, buf, count);
 }
 
 void ClosePtyShell(int fd)
 {
 if(pid>0)
 {
 kill(pid,3);
 kill(pid,6);
 kill(pid,9);
 pid=0;
 }
 
 if(ttyfd != -1)
 close(fd);
 
 }
 
 int ReadFile( char *FullName , HWND hedit ) //TODO: set max size of file limit.
 {
 FILE *fd;
 char  OneChar;
 char *AllChar;
 int index = 0;
 
 struct stat file;
 
 if( lstat( FullName, &file) < 0 ) {
 printf("lstat error\n");
 return -1;
 }
 
 //184391 -1421 13822192 -1434 286098 10611209 65536
 AllChar = malloc ( file.st_size + 1);
 
 //printf("\n=========File Start==========\n");
 if( ( fd = fopen( FullName , "r" ) ) != NULL ) {
 while( (( OneChar = ( getc( fd ) ) ) != EOF) && ( index++ < file.st_size ) ) {
 putchar ( OneChar );
 AllChar[ index - 1 ] = OneChar;
 }
 }
 
 //printf("=========File Enddd==========\n");
 
 AllChar[ index ] = '\0';
 
 SendMessage( hedit , WM_SETTEXT, 0, (LPARAM) (LPSTR)AllChar);
 
 free( AllChar );
 
 fclose( fd );
 
 return 0;
 }
 
 int load_ini(void)
 {
 FILE *fp_ini;
 fp_ini=fopen(INI_FileName,"r");
 if (fp_ini!=NULL)
 {
 
 fscanf(fp_ini,"UP=%s\n",keyup_define);
 fscanf(fp_ini,"DOWN=%s\n",keydown_define);
 fscanf(fp_ini,"LEFT=%s\n",keyleft_define);
 fscanf(fp_ini,"RIGHT=%s\n",keyright_define);
 fscanf(fp_ini,"AUTOMAX=%d\n",&listboxmax);
 fscanf(fp_ini,"AUTOSCROLL=%d\n",&autoscroll);
 fscanf(fp_ini,"AUTOCLS=%d\n",&autocls);
 fclose(fp_ini);
 
 return 1;
 }
 else return 0;
 }
 
 int save_ini(void)
 {
 FILE *fp_ini;
 fp_ini=fopen(INI_FileName,"w");
 if(fp_ini!=NULL)
 {
 
 fprintf(fp_ini,"UP=%s\n",keyup_define);
 fprintf(fp_ini,"DOWN=%s\n",keydown_define);
 fprintf(fp_ini,"LEFT=%s\n",keyleft_define);
 fprintf(fp_ini,"RIGHT=%s\n",keyright_define);
 fprintf(fp_ini,"AUTOMAX=%d\n",listboxmax);
 fprintf(fp_ini,"AUTOSCROLL=%d\n",autoscroll);
 fprintf(fp_ini,"AUTOCLS=%d\n",autocls);
 fclose(fp_ini);
 return 1;
 }
 else return 0;
 }
 
 int insert_string(HWND hwnd,char *STR) //这段子程序是为了实现edit控件的粘贴功能,因为edit控件不支持从焦点插入字符串的操作,只好给它发送WM_CHAR消息模拟键盘输入将字符串拆成一个个字符逐个输入
 {
 int i;
 for (i=0;i<strlen(STR);i++)
 {
 SendMessage(hwnd,WM_CHAR,STR[i],0);
 }
 }
 
 [/code:1]
 [/quote]
 | 
 
×本帖子中包含更多资源您需要 登录 才可以下载或查看,没有账号?注册  |