YC++创建HTML工具栏
在YC++中,既可以用CreateWindowEx(WS_EX_TOOLWINDOW,TOOLBARCLASSNAME,...)等Win32函数创建
工具栏(例子见YC01/examples/ycp.cpp), 也可以用其API函数:
HWND YXB_Window(YHOOKPROC wnd_hook,void *pUserData,DWORD dwExStyle,DWORD dwStyle,LPCSTR lpWindowName,
int X,int Y,int nWidth,int nHeight,HWND hWndParent,int winType);
创建工具栏。
/*****************************************************************************************************************/
这个函数,用HTML文本和CSS样式表现工具栏的界面,用javascript脚本和DOM控制工具栏的元素,用C/C++实现程序逻辑。
这样的工具栏,不仅很容易做到界面华丽,还可以使界面和逻辑分开设计,便于调试。 并且可做到使界面源代码与平台无关。
如在Windows做的工具栏, 不用修改源代码就可以用在unix,linux等其它操作系统中。
下面对该函数的参数进行说明, 并列出示例代码。
/*****************************************************************************************************************/
参数
/*****************************************************************************************************************/
wnd_hook
回调函数指针,当发生与窗口(用该函数创建的)有关的事件时,将调用它。
其格式为:int WINAPI wnd_hook(HWND hwnd,UINT iMessage,UINT wParam,LONG lParam,void *pUserData);
参数
hwnd HTML所在窗口的句柄。
iMessage 消息类型。
wParam, lParam, 消息可能带有数据,数据可用wParam和lParam来表示。
pUserData 用户数据。用户创建窗口时传给系统,系统通过回调函数传回用户,这样可
避免使用全局变量。
//
回调函数wnd_hook可以让网页与调用者之间进行数据通信。目前有4种系统事件和无数种自定义事件
发生时会自动调用其回调函数。例如:
int WINAPI html_hook(HWND hwnd,UINT iMessage,UINT wParam,LONG lParam,void *pUserData)
{
switch(iMessage)
{
case YM_ONLOAD: break; //网页解析完毕并且onload函数执行完后。
case YM_CLOSE: break; //网页所在窗口关闭前一刻。
//wParam=0表示窗口未被javascript函数resizeTo缩放过
case YM_PAINT: //网页在其窗口中被刷新显示时。
YIMG *pimg;
pimg = (YIMG*)wParam; //网页所在的图象指针
RECT *pClientRect;
pClientRect = (RECT*)lParam; //网页被刷新的区域
return TRUE; //返回值为TRUE,表示调用者处理了这个事件
case YM_KEYDOWN: //有键按下时。其用法见文件: yctool.h
int ctrl_flag,shift_flag,vkValue;
ctrl_flag = wParam & CTRL_MASK; //按下Ctrl键
shift_flag = wParam & SHIFT_MASK; //按下Shift键
vkValue = wParam & KEY_MASK; //键值
return TRUE; //返回值为TRUE,表示调用者处理了这个事件
case (任何>=0 && <0x7f000000的整数消息):
当在网页中调用了YC扩展javascript函数
hook(iMessage, ...)时,将调用回调函数,
其消息iMessage由用户自定义。
return (任意整数);
case (任何<=-1的整数消息):
为了方便C/C++向javascript传递字符串,特规定
消息为负时返回字符串指针。
return 字符串指针;
}
return FALSE;
}
/*****************************************************************************************************************/
pUserData
它是调用者传给回调函数wnd_hook的一个指针(或整数)。
/*****************************************************************************************************************/
lpWindowName
窗口名字。
/*****************************************************************************************************************/
dwExStyle,dwStyle
它们定义了窗口的格式。其意义与WIN32函数CreateWindowEx中的一样。
/*****************************************************************************************************************/
X,Y,nWidth,nHeight
它们定义了窗口的位置和大小。其意义与WIN32函数CreateWindowEx中的一样。
/*****************************************************************************************************************/
hWndParent 父窗口句柄
/*****************************************************************************************************************/
winType 要创建的窗口之类型。这里应设置为: WT_HTML
/*****************************************************************************************************************/
返回值 返回值表示被创建的窗口之句柄。若返回值为NULL,表示窗口未创建成功
/*****************************************************************************************************************/
创建工具栏窗口后,还需向窗口发送工具栏网页
/*****************************************************************************************************************/
例子:
/*****************************************************************************************************************/
该例子需将YC++的下列7个文件拷入你的源程序所在目录:
YC01/yxbapi.dll C/C++编译器, 浏览器内核库
YC01/yxbimg.dll 图象, 动画解码库
YC01/yxbext.dll 浏览器内核交互代码库
YC01/yc.ah C/C++编译器头文件包
YC01/yc.cmp C/C++编译器错误信息
YC01/yctool.bmp 工具栏图象文件
YC01/include/ycapi.h 用其它编译器运行该例时所需头文件
YC01/include/yxbapi.lib 用其它编译器运行该例时所需库文件, 如VC6.0
/*****************************************************************************************************************/
/*****************************************************************************************************************/
/*****************************************************************************************************************/
将下列代码拷入名字任取的文件, 如: blog3a.cpp
在YC++中, 用
<文件 打开或创建cpp源程序>
调入blog3a.cpp, 再用
<工具 执行>
运行blog3a.cpp
或在dos中, 用 ycc blog3a.cpp 生成 blog3a.exe, 再运行blog3a.exe
在VC++中, 用 cl blog3a.cpp 生成 blog3a.exe, 再运行blog3a.exe
/*****************************************************************************************************************/
/*****************************************************************************************************************/
#ifndef YCC
#include
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "yxbapi.lib")
#include "ycapi.h"
#endif
#define var const int
var ADDRESS_HIGH = 27;
var TOOL_HIGH = 24;
var ID_toolBarExist = 0;
var ID_toolbmp = 1;
var ID_go = 2;
var ID_edit = 3;
var ID_backward = 4;
var ID_MENU_backward = 5;
var ID_forward = 6;
var ID_MENU_forward = 7;
var ID_stop = 8;
var ID_refresh = 9;
var ID_home = 10;
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
/创建主窗口. 用YC++的API函数创建, 它不需要注册. 也可以用Win32函数创建主窗口
int WINAPI MainWndProc(HWND hwnd,UINT iMessage,UINT wParam,LONG lParam,void *pUserData);
HWND hwnd = YXB_Window(MainWndProc,NULL,0,
WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_SYSMENU,
"a",110,50,800,600,NULL,WT_WIN);
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
int WINAPI address_hook(HWND hwnd,UINT iMessage,UINT wParam,LONG lParam,void *pUserData)
{
HWND m_hToolWnd = *(HWND*)pUserData;
switch(iMessage)
{
case YM_KEYDOWN:
PostMessage(GetParent(hwnd), WM_KEYDOWN, wParam, lParam);
break;
case YM_ONLOAD:
SetFocus(m_hToolWnd); //输入焦点传给工具栏
YXB_RunJScript(m_hToolWnd, "set_edit_value('How do you do?')"); //编辑框初始化
break;
case ID_edit: break;
case ID_go: MessageBox(hwnd, "go", "YC++", MB_ICONHAND|MB_OK); break;
case ID_MENU_backward: MessageBox(hwnd, "MENU_backward", "YC++", MB_ICONHAND|MB_OK); break;
case ID_MENU_forward: MessageBox(hwnd, "MENU_forward", "YC++", MB_ICONHAND|MB_OK); break;
case ID_backward: MessageBox(hwnd, "backward", "YC++", MB_ICONHAND|MB_OK); break;
case ID_forward: MessageBox(hwnd, "forward", "YC++", MB_ICONHAND|MB_OK); break;
case ID_stop: MessageBox(hwnd, "stop", "YC++", MB_ICONHAND|MB_OK); break;
case ID_refresh: MessageBox(hwnd, "refresh", "YC++", MB_ICONHAND|MB_OK); break;
case ID_home: MessageBox(hwnd, "home", "YC++", MB_ICONHAND|MB_OK); break;
}
return FALSE;
}
int WINAPI MainWndProc(HWND hwnd,UINT iMessage,UINT wParam,LONG lParam,void *pUserData)
{
RECT mRect;
switch(iMessage)
{
case WM_CREATE:
/创建HTML工具栏//
int WINAPI address_hook(HWND hwnd,UINT iMessage,UINT wParam,LONG lParam,void *pUserData);
static HWND m_hToolWnd; //工具栏窗口
m_hToolWnd = YXB_Window(address_hook, &m_hToolWnd,0,YS_NOWRERR,NULL,0,0,0,0, hwnd, WT_HTML);
//向工具栏窗口发送网页
WEB_PAGE apage;
memset(&apage,0,sizeof(apage));
apage.click_page = 3;
apage.href = "tool.htm";
SendMessage(m_hToolWnd, WM_COMMAND, WEB_A, (int)(WEB_PAGE*)&apage);
return FALSE;
case WM_SIZE:
GetClientRect(hwnd, &mRect);
MoveWindow(m_hToolWnd,mRect.left,mRect.top, mRect.right, ADDRESS_HIGH + TOOL_HIGH + 4, TRUE); //若为 FALSE 左右缩放时, rebar 右边部分不能刷新
return FALSE;
case WM_DESTROY: PostQuitMessage(0); return FALSE;
case WM_KEYDOWN:
if(wParam == VK_ESCAPE) DestroyWindow(hwnd);
return FALSE;
case WM_PAINT: //每当窗口客户区有需要重画的区域时, Windows便向这个窗口发出WM_PAINT消息.
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
YIMG yimg;
memset(&yimg,0,sizeof YIMG);
yimg.hdc = ps.hdc; //通过这个设置, 可以将窗口客户区当作一幅图象来操作
GetClientRect(hwnd, &mRect);
用YC内置函数YXB_ImageFill在图象yimg中画出下面四个单色矩形/
YXB_ImageFill(&yimg, mRect.left, mRect.top, mRect.right-mRect.left,
mRect.bottom-mRect.top, RGB(130,150,160));
YXB_ImageFill(&yimg, 100,100, 200,150, RGB(100,0,0));
YXB_ImageFill(&yimg, 150,150, 200,150, RGB(0,100,0));
YXB_ImageFill(&yimg, 200,200, 200,150, RGB(0,0,100));
EndPaint(hwnd, &ps);
return FALSE;
}
return DefWindowProc(hwnd,iMessage,wParam,lParam);
}
/*****************************************************************************************************************/
/*****************************************************************************************************************/
/*****************************************************************************************************************/
将下列HTML文本拷入指定文件: tool.htm
/*****************************************************************************************************************/
oncontrol="hook(ID_edit, event.ctrl)"
style="position:absolute; font-family:Tahoma; font-size:16;">
οnchange="hook(ID_go);"
value="转到"
content="icosize(16,16) paint(19,0) move(19,1) xpress(14,0) disabled(13,0) edgepaint=0 edgemove=1"
src="yctool.bmp"
style="position:absolute; font-family:Tahoma; font-size:16; height=25;">
<script language=javascript>
var ADDRESS_HIGH = 27;
var TOOL_HIGH = 24;
var ID_toolBarExist = 0;
var ID_toolbmp = 1;
var ID_go = 2;
var ID_edit = 3;
var ID_backward = 4;
var ID_MENU_backward = 5;
var ID_forward = 6;
var ID_MENU_forward = 7;
var ID_stop = 8;
var ID_refresh = 9;
var ID_home = 10;
document.body.size = TOOL_HIGH; //标记的属性size>0时, 表示页面用于工具栏
function dialog_init(aa,bb)
{
backward.disabled = aa;
forward.disabled = bb;
}
function body_onload()
{
hook(ID_toolbmp,go.img);
edit.focus();
body_onresize();
}
function body_onresize()
{
addr_pos = TOOL_HIGH+1;
toolp.style.left = 2;
toolp.style.top = 2;
for(ii=0; ii
edit.style.top = addr_pos + 1;
edit.style.left = addr.width + 3;
edit.style.width = document.body.clientWidth - go.width - edit.style.left - 8;
edit.style.height = ADDRESS_HIGH;
addr.style.left = 2;
addr.style.top = addr_pos + (edit.style.height - addr.height)/2 + 1;
go.style.top = addr_pos + (edit.style.height - go.height)/2 + 1;
go.style.left = edit.style.left + edit.style.width + 3;
}
function set_edit_value(ss)
{
edit.value = ss;
}
function get_edit_value()
{
return edit.value;
}
function set_edit_length(nn)
{
edit.lines = nn;
}
function tool_onchange()
{
var nn, selp=event.srcElement;
switch(selp)
{
case backward:
if(event.ctrl == 1) nn = ID_backward;
else nn = ID_MENU_backward;
break;
case forward:
if(event.ctrl == 1) nn = ID_forward;
else nn = ID_MENU_forward;
break;
case stop:
nn = ID_stop;
break;
case refresh:
nn = ID_refresh;
break;
case home:
nn = ID_home;
break;
}
hook(nn, selp.clientLeft + (selp.clientTop<<16), selp.clientWidth + (selp.clientHeight<<16));
}
</script>