用最简单的方法制作各种程序界面

窗口界面接口ycwin.cpp

ycwin.cpp提供了创建窗口界面的接口,它有3种运行方式:

  1. 独立运行。
  2. 被C/C++程序调用。
  3. 被Javascript程序调用。

其源码如下:

……
struct ycwinCLASS
{
        YHTML *phtml;                  //当前显示的HTML对象
        YHTML *oldhtml;                //待删除的HTML对象
        int nTimer;                    //定时器
        int posx,posy,width,height;    //定义窗口位置和大小
        byte attr;
        byte esc;                      //是否可以用 Esc 键退出程序
        virtual void _stdcall createWindow(char *htmfile=0,int htmlen=0,
                                           int escFlag=0,int popFlag=0,
                                           int attrFlag=0,char *srcfile=0);
        virtual void _stdcall loop();  //消息循环函数
        virtual int _stdcall exist();  
};
……

                          ycwin.cpp所用头文件yc.h

ycwin.cpp源码:

#include "yc.h"
long stdcall WndProc(HWND hwnd,unsigned iMessage, unsigned wParam,long lParam)
{
    YHTML *phtml = YCWIN.phtml;
    switch(iMessage)
      {
        case WM_TIMER:
             if(YCWIN.oldhtml)
               {
                 YC_htmlFree(YCWIN.oldhtml);  //释放旧页面
                 YCWIN.oldhtml = nullptr;
               }
             YCHTML->wm_timer(phtml);         //处理网页的定时功能
             if(YCHTML->is_stopping(phtml) && YCHTML->can_exit(phtml))
                                  DestroyWindow(hwnd); //判断是否设置了退出标志
             return FALSE;
        case WM_DESTROY:        //程序退出时进行销毁窗口处理
             get_winattr(phtml,0);         //只用于yc.exe
             KillTimer(hwnd,YCWIN.nTimer); //销毁定时器
             YCWIN.phtml = nullptr;
             YC_htmlFree(phtml);           //释放当前页面
             set_ycexe_wnd(nullptr);	   //只用于yc.exe
             PostQuitMessage(0);
             return FALSE;
        case WM_CLOSE:
             if(YC_jsRun(phtml,L"!window.can_exit || can_exit()"))//设置退出标志
                                                      YCHTML->page_stop(phtml);
             return FALSE;
        case WM_SYSKEYDOWN:
        case WM_KEYDOWN:
             if(wParam==VK_ESCAPE && !YCWIN.esc) 
               {
                 PostMessageA(hwnd,WM_CLOSE,0,0);
               }
             if(wParam==VK_F12 && !YCWEB->ctrlKey() && !YCWEB->shiftKey())
               {
                 CloseWindow(hwnd);
               }
             else if(wParam==VK_F11 && !YCWEB->ctrlKey() && !YCWEB->shiftKey())
               {
                 show_window();
               }
             else    YCHTML->wm_keydown(phtml,wParam);
             if(!YCWIN.attr)   YCWEB->html_key_proc(phtml,wParam);
             break;
        case WM_CHAR:
             YCHTML->wm_char(phtml,wParam);
             return FALSE;
        case WM_KEYUP:
             YCHTML->wm_keyup(phtml,wParam);
             return FALSE;
        case WM_SIZE:
             YCHTML->wm_size(phtml,LOWORD(lParam),HIWORD(lParam));
        case WM_MOVING:
             RECT rc;
             if(!IsIconic(hwnd) && !get_popup(phtml))
               {
                 int maxV = IsZoomed(hwnd);            //获取窗口最大化状态
                 if(!maxV)
                   {
                     GetWindowRect(hwnd,&rc);
                     YC_jsRunf(phtml,L`localStorage.posx=%d;  //保存窗口位置
                                       localStorage.posy=%d;
                                       localStorage.width=%d; //保存窗口大小
                                       localStorage.height=%d`,
                            rc.left,rc.top,rc.right-rc.left, rc.bottom-rc.top);
                   }
                 YC_jsRunf(phtml,L"localStorage.winmax = %d",maxV);//保存最大状态
                 SetWindowLongA(hwnd,GWL_USERDATA,maxV);  //记录窗口最大化状态
               }
             break;
        case WM_SETFOCUS:
             YCHTML->wm_setfocus(phtml);
             return FALSE;
        case WM_KILLFOCUS:
             YCHTML->wm_killfocus(phtml);
             return FALSE;
        case WM_MOUSEWHEEL:
             YCHTML->wm_mousewheel(phtml,wParam);
             return FALSE;
        case WM_MOUSEMOVE:
             YCHTML->wm_mousemove(phtml,LOWORD(lParam),HIWORD(lParam));
             return FALSE;
        case WM_LBUTTONDOWN:
        case WM_LBUTTONDBLCLK:
             YCHTML->wm_lbuttondown(phtml,LOWORD(lParam),HIWORD(lParam),
                                                   iMessage==WM_LBUTTONDBLCLK);
             return false;
        case WM_RBUTTONDOWN:
        case WM_RBUTTONDBLCLK:
             YCHTML->wm_rbuttondown(phtml,iMessage == WM_RBUTTONDBLCLK);
             return false;
        case WM_LBUTTONUP:
             YCHTML->wm_lbuttonup(phtml);
             return false;
        case WM_RBUTTONUP:
             YCHTML->wm_rbuttonup(phtml);
             break;
        case WM_SETCURSOR:
             if(YCHTML->wm_setcursor(phtml))   return true;
             break;
        case WM_USER + 2002:
             get_winattr(phtml,1,wParam,lParam);
             return true;
        case WM_ACTIVATE:
             if(LOWORD(wParam) != WA_INACTIVE)
                 YC_jsRun(phtml,L"window.yced_OnActivate && yced_OnActivate()");
             return true;
        case WM_PAINT:
             if(GetUpdateRect(hwnd,&rc,0) == 0)   break;
             PAINTSTRUCT ps;
             BeginPaint(hwnd,&ps);
             YIMG *pimg = YCHTML->draw_page(phtml,rc.left,rc.top,
                                            rc.right-rc.left,rc.bottom-rc.top);
             if(pimg)   BitBlt(ps.hdc, rc.left,rc.top,pimg->width,
                                           pimg->height,pimg->hdc,0,0,SRCCOPY);
             EndPaint(hwnd,&ps);
             return true;
      }
    return DefWindowProcA(hwnd,iMessage,wParam,lParam);
}

int get_popup(YHTML *phtml,bool popFlag=false)
{
    if(popFlag && YC_jsRun(phtml,L"localStorage.popup == undefined"))
                                                           save_popup(phtml,1);
    return YC_jsRun(phtml,L"localStorage.popup");
}

void save_popup(YHTML *phtml,int mval)
{
    YC_jsRunf(phtml,L"localStorage.popup = %d",mval);        //保存窗口满屏状态
}

void get_winattr(YHTML *phtml,int type,int wParam=0,int lParam=0)
{
   if(!YC_jsRun(phtml,L"window.yced_getWinAttr && yced_getWinAttr()"))  return;
   if(type)  YC_jsRunf(phtml,L"yced_mouse_hook_func(%d,%d)",wParam,lParam);
   else      InvalidateRect(NULL,NULL,FALSE);
}

void show_window()
{
    YHTML *phtml = YCWIN.phtml;
    YCWIN.posx = YC_jsRun(phtml,L"localStorage.posx");   //获取窗口位置大小
    YCWIN.posy = YC_jsRun(phtml,L"localStorage.posy");
    YCWIN.width = YC_jsRun(phtml,L"localStorage.width");
    YCWIN.height = YC_jsRun(phtml,L"localStorage.height");
    YCWEB->set_user_window_size(YCWIN.posx,YCWIN.posy,YCWIN.width,YCWIN.height);

    int popV = !get_popup(phtml);   //获取窗口满屏状态
    save_popup(phtml,popV);         //保存窗口满屏状态
    int maxV = YC_jsRun(phtml,L"localStorage.winmax");     //获取窗口最大化状态

    SetWindowLongA(phtml->hwnd,GWL_USERDATA,popV || maxV);   //记录窗口状态
    YCWEB->show_window(phtml->hwnd,YCWIN.posx,YCWIN.posy,    //根据状态显示窗口
                                            YCWIN.width,YCWIN.height,popV,maxV);
}

void set_ycexe_wnd(void *hwnd)
{
    if(YCWIN.attr)  YC_system(YCSYS_ycexe_wnd,hwnd,TRUE);
}

void stdcall ycwin_createWindow(YHTML *phtml,byte *obj_ptr,JSVAL *pJval,
                                                        int argnum,JSVAL *argval)
{
    //实现Javascript语句: pwin.createWindow("yc.htm"...)
    int htmlen = 0;
    char *htmfile = null;
    if(js_arg_str(0,argnum,argval))      //第0个形参argval[0]为文件名或网页名
      {
         htmfile = YC_wideToChar(&htmlen,argval[0].wptr,argval[0].len);
         if(argnum<=1 || argval[1].type!=JS_null)   htmlen = 0;
      }

    YCWIN.createWindow(htmfile, htmlen,
                                js_arg_bool(1,argnum,argval),       //第1个形参
                                js_arg_bool(2,argnum,argval),       //第2个形参
                                js_arg_bool(3,argnum,argval),       //第3个形参
                                htmlen ? phtml->URLptr : null);
    free(htmfile);
    YCJIT->create_cppObject(phtml,pJval,&frame_data); //创建Javascript对象frame
}

void stdcall ycwin_exist(YHTML *phtml,byte *obj_ptr,JSVAL *pJval,
                                                      int argnum,JSVAL *argval)
{
    //实现Javascript语句: pwin.exist()
    pJval->type = JS_bool;
    pJval->valBool = YCWIN.exist();
}

void stdcall frame_loop(YHTML *phtml,byte *obj_ptr,JSVAL *pJval,
                                                      int argnum,JSVAL *argval)
{
    //实现Javascript语句: frame.loop()
    YCWIN.loop();
}

char STR_className[256];
void ycwinCLASS::createWindow(char *htmfile,int htmlen,int escFlag,
                                          int popFlag,int attrFlag,char *srcfile)
{
    //实现c/c++语句: pwin->createWindow("yc.htm",...)
    YCWIN.esc = escFlag;
    YCWIN.attr = attrFlag;
    lstrcpynA(STR_className,htmfile ? htmfile : "yjx",sizeof STR_className);

    WNDCLASSEXA wc = {};
    wc.cbSize = sizeof(wc);
    wc.lpszClassName = STR_className;
    wc.lpfnWndProc = WndProc;
    wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
    wc.style = CS_DBLCLKS;
    char exefile[MAX_PATH];
    GetModuleFileNameA(NULL,exefile,MAX_PATH);
    wc.hIcon = ExtractIconA(NULL,exefile,0);  //从exe文件中取出图标
    if(!RegisterClassExA(&wc))   return;      //注册窗口

    HWND hwnd = CreateWindowExA(0,STR_className,null,WS_OVERLAPPEDWINDOW,
                                                0,0,0,0,null,null,null,null);
    YPOST mPost = {};
    if(htmlen)
      {
        mPost = { htmfile, htmlen, POST_IS_HTML };
        htmfile = srcfile;
      }

    phtml = YC_htmlLoad(htmfile,&mPost,hwnd,
                       [](YHTML *phtml,unsigned iMessage,unsigned,long,void*)
                       {
                         switch(iMessage)
                           {
                             case YM_Create:  //点击链接进入新页面时收到该消息
                                  YCWIN.oldhtml = YCWIN.phtml; //保存旧页面指针
                                  YCWIN.phtml = phtml;  //设置新页面指针
                                  break;
                           }
                         return 0;
                       },null,null,WEB_HISTORY);

    nTimer = SetTimer(hwnd,1,10,NULL);
    YC_jsRunf(phtml,L"show_window = 0x%x;",show_window); //把函数传给 yc.htm
    save_popup(phtml,!get_popup(phtml,popFlag));         //窗口满屏状态取反
    set_ycexe_wnd(hwnd);
    show_window();
}

void ycwinCLASS::loop()
{
    //实现c/c++语句:  pwin->loop()
    MSG msg;
    while(GetMessageA(&msg, null, 0, 0))
      {
        TranslateMessage(&msg);
        DispatchMessageA(&msg);
      }
    UnregisterClassA(STR_className,null);
}

int ycwinCLASS::exist()
{
    //实现c/c++语句:  pwin->exist()
    char *cmdbuf = YCWEB->strdupA(GetCommandLineA());
    if(cmdbuf)
      {
        char *argv[8];
        int argc = YCWEB->getArgA(cmdbuf,argv,sizeof(argv)/sizeof(argv[0]));
        if(argc>=3 && !strcmp(argv[2],"$$$$$$"))
          {
            free(cmdbuf);
            YC_cppRun("yctest.cpp");  //运行内存泄漏对话框程序yctest.cpp
            return 1;
          }
        free(cmdbuf);
      }
    HWND hwnd = (HWND)YC_system(YCSYS_ycexe_wnd,0,FALSE);
    if(hwnd && IsWindow(hwnd))  //判断程序是否已经运行
      {
        int dwStyle = GetWindowLongA(hwnd,GWL_USERDATA) ?
                                                SW_SHOWMAXIMIZED : SW_SHOWNORMAL;
        if(IsIconic(hwnd))  ShowWindow(hwnd,dwStyle);
        SetForegroundWindow(hwnd);      //如果程序已经运行,则将它显示在最上面
        return 1;
      }
    return 0;
}

//定义对象pwin的方法
JS_EXT_METHOD ycwin_method[] = { { L"createWindow",    ycwin_createWindow  },
                                 { L"exist",           ycwin_exist  },
                                 0,};

//定义对象frame的方法
JS_EXT_METHOD frame_method[] = { { L"loop",    frame_loop  },
                                 0,};

jsDATA ycwin_data = { null, ycwin_method, L"ycwin" };  //用于创建pwin对象
jsDATA frame_data = { null, frame_method, L"frame" };  //用于创建frame对象
ycwinCLASS YCWIN;

void main(void **pObj,int isScript)
{
    if((int)pObj < 1000)  //当独立运行本程序时, 有argc = pObj
      {
        char **argv = (char**)isScript;
        YCWIN.createWindow((int)pObj<=1 ? "https://www.ha123.com" : argv[1]);
        YCWIN.loop();
      }
    else  if(isScript)   *pObj = &ycwin_data; //当Javascript调用本程序时
    else                 *pObj = &YCWIN;      //当C/C++调用本程序时
}

                            c/c++代码文件:ycwin.cpp

    如果用Javascript或c/c++调用ycwin.cpp,无需编译生成ycwin.exe,系统将自动处理ycwin.cpp。
若要独立运行ycwin.cpp,则需进行下列步骤:
编译:用YC命令: ycc ycwin.cpp 生成 ycwin.exe
运行:在cmd界面执行ycwin url后,将显示url页面。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值