win32第十二天

一.滚动条
1.分类
风格:SBS_VERT----垂直滚动条
      SBS_HORZ----水平滚动条
2.类名:SCROLLBAR
新建工程:WINSB
#define IDC_SB_R 4001
#define IDC_SB_G 4002
#define IDC_SB_B 4003
//主消息处理函数
case WM_CREATE:{
int x=4,y=4;
HWND hwndSB=CreateWindowEx(0,"SCROLLBAR",NULL,WS_CHILD|WS_VISIBLE|SBS_VERT,x,y,50,300,hWnd,(HMENU)IDC_SB_R,g_hInstance,NULL);
//设置滚动范围
SendMessage(hwndSB,SBM_SETRANGE,0,255);
SendMessage(hwndSB,SBM_SETPOS,128,FALSE);
//创建第二个
HWND hwndSB=CreateWindowEx(0,"SCROLLBAR",NULL,WS_CHILD|WS_VISIBLE|SBS_HORZ,x+=54,y+=125,150,50,hWnd,(HMENU)IDC_SB_G,g_hInstance,NULL);
//设置滚动范围
SendMessage(hwndSB,SBM_SETRANGE,0,255);
SendMessage(hwndSB,SBM_SETPOS,128,FALSE);
//创建第三个
HWND hwndSB=CreateWindowEx(0,"SCROLLBAR",NULL,WS_CHILD|WS_VISIBLE|SBS_VERT,x+=154,y-=125,50,300,hWnd,(HMENU)IDC_SB_B,g_hInstance,NULL);
//设置滚动范围
SendMessage(hwndSB,SBM_SETRANGE,0,255);
SendMessage(hwndSB,SBM_SETPOS,128,FALSE);
}
3.窗口消息
SBM_SETRANGE----设置滚动范围
wParam---最小位置
lParam----最大位置
SBM_GETRANGE---获取滚动范围
wParam---表示最小位置的int变量的指针
lParam----表示最大位置的int变量的指针
SBM_SETPOS-设置滚动位置
wParam--滚动位置
lParam--是否重绘TRUE/FALSE
SBM_GETPOS--获取滚动位置,通过SendMessage返回
wParam--0
lParam---0
4.通知消息
独立的窗口消息
WM_HSCROLL---水平滚动
WM_VSCROLL----垂直滚动
wParam --LOWORD滚动码,HIWORD当前位置(仅对SB_THUMBTRACK/SB_THRUMPOSITION滚动码有效)
lParam--滚动条控件句柄
滚动码:
SB_LINELEFT---点左键头
SB_LINERIGHT--点右键头
SB_PAGELEFT---点左空白
SB_PAGERIGHT--点右空白
SB_LINEUP     点上键头
SB_LINEDOWN   点下键头
SB_PAGEUP      点上空白
SB_PAGEDOWN   点下空白
SB_THUMBTRACK------拖动滑块
SB_THUMBPOSITION---施放滑块
//为以上程序实现上述功能
case WM_HSCROLL:
{
int nPos=SendMessage((HWND)lParam,SBM_GETPOS,0,0);
switch(LOWORD(wParam)){
case SB_LINELEFT:
nPos--;
break;
case SB_LINERIGHT:
nPos++;
break;
case SB_PAGELEFT:
nPos-=32;
break;
case SB_PAGERIGHT:
nPos+=32;
break;
case SB_THUMBTRACK:
nPos=(HIWORD)wParam;
break;
}
SendMessage((HWND)lParam,SBM_SETPOS,nPos,TRUE);
InvalidateRect(hWnd,NULL,TRUE);
}
//垂直的也相当类似
case WM_VSCROLL:
{
int nPos=SendMessage((HWND)lParam,SBM_GETPOS,0,0);
switch(LOWORD(wParam)){
case SB_LINEUP:
nPos--;
break;
case SB_LINEDOWN:
nPos++;
break;
case SB_PAGEUP:
nPos-=32;
break;
case SB_PAGEDOWN:
nPos+=32;
break;
case SB_THUMBTRACK:
nPos=(HIWORD)wParam;
break;
}
SendMessage((HWND)lParam,SBM_SETPOS,nPos,TRUE);
InvalidateRect(hWnd,NULL,TRUE);
}
//实现当拖动滑块的时候改变客户区的背景颜色
//添加一个变量跟踪窗口大小
static SIZE sizeClient={0};
case WM_SIZE:
sizeClient.cx=LOWORD(lParam);
sizeClient.cy=HIWORD(lParam);
return 0;
//重新刷下
case WM_ERASEBKGND:
HBRUSH hbrushBkgnd=CreateSolidBrush(RGB(SendMessage(GetDlgItem(hWnd,IDC_SB_R),SBM_GETPOS,0,0),SendMessage(GetDlgItem(hWnd,IDC_SB_G),SBM_GETPOS,0,0),SendMessage(GetDlgItem(hWnd,IDC_SB_B),SBM_GETPOS,0,0));
RECT rcClient={0,0,sizeClient.cx,sizeClient.cy};
FillRect((HDC)wParam,&rcClient,hbrushBkgnd);
DeleteObject(hbrushBkgnd);
return 0;
//让其刚开始便刷不至于透明显示
GetClientRect(hWnd,&
//如何想不刷子窗口的话,在主窗口添加一个风格
WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN
//如何使用
case SB_THUMBPOSITION:
则在拖动的时候不变颜色,但是当一松手,颜色马上改变。而SB_THUMBTRACK是不断的更新颜色。


实现另一个程序:显示一幅图片,当窗口足够大时,图片显示在窗口的中央,当窗口小时,自动出现滚动条,当窗口越小,滑块越小,滚动范围越大。类似于浏览器等其它软件中的效果一样。
新建工程:WinScroll
在窗口类中更改背景颜色(深灰色):
wcex.hbrBackground=GetSysColorBrush(COLOR_APPWORKSPACE);
添加一个位图资源,.bmp
#include "resource.h"
窗口处理函数中:
static HBITMAP hbmpImage=NULL;
static BITMAP bmpImage={0};
static HDC hdcImage=NULL;
static HGDIOBJ hbmpOld=NULL;
static SIZE sizeClient={0};
case WM_CREATE:
hbmpImage=LoadBitmap(g_hInstance,MAKEINTRESOURCR(IDB_iMAGE));
GetObject(hbmpImage,sizeof(bmpImage),&bmpImage);
HDC hDC=GetDC(hWnd);
hdcImage=CreateCompatibleDC(hDC);
hbmpOld=SelectObject(hdcImage,hbmpImage);
ReleaseDC(hWnd,hDC);
return 0;
case WM_SIZE:
sizeClient.cx=LOWORD(lParam);
sizeClient.cy=HIWORD(lParam);
case WM_DESTROY:
SelectObject(hdcImage,hbmpOld);
DeleteObject(hbmpImage);
DeleteDC(hdcImage);
PostQuit(0);
return 0;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hDC=BeginPaint(hWnd,&ps);
BitBlt(hDC,max((sizeClient.cx-bmpImage.bmWidth)/2,0),max((sizeClient.cy-bmpImage.bmHeight)/2,0),min(sizeclient.cx,bmpImage.bmWidth),
min(sizeClient.cy,bmpImage.bmHeight),hdcImage,0,0,SRCCOPY);
EndPaint(hWnd,&ps);
//现在可以看到效果,接下来加上滚动条
在窗口类中添置风格:
WS_HSCROLL|WS_VSCROLL|wS_ovERLAPPEDWInDOW
case WM_SIZE:
SCROLLINFO si;
si.cbSize=sizeof(si);
si.fMask=SIF_PAGE|SIF_RANGE;
si.nPage=sizeClient.cx/2;
si.nMin=0;
si.nMax=bmpImage.bmWidth-sizeClient.cx+si.nPage;
SetScrollInfo(hWnd,SB_HORZ,&si,TRUE);
si.nPage=sizeClient.cy/2;
si.nMax=bmpImage.bmHeight-sizeClient.cy+si.nPage;
SetScrollInfo(hWnd,SB_VERT,&si,TRUE);
//对滚动条消息做处理
case WM_HSCROLL:{
SCROLLINFO si;
si.cbSize=sizeof(si);
si.fMask=SIF_ALL;
GetScrollInfo(hWnd,SB_HORZ,&si);
switch(LOWORD(wParam)){
case SB_LINELEFT:
si.nPos--;
break;
case SB_LINERIGHT:
si.nPos++;
break;
case SB_PAGELEFT:
si.nPos-=si.nPage;
break;
case SB_PAGERigHT:
si.nPos+=si.nPage;
break;
case SB_THUMBTRACK:
si.nPos=si.nTrackPos;
break;
}
si.fMask-SIF_POS;
SetScrollInfo(hWnd,SB_HORZ,&si,TRUE);
InvalidateRect(hWnd,NULL,TRUE);
return 0;
}
case WM_VSCROLL:{
SCROLLINFO si;
si.cbSize=sizeof(si);
si.fMask=SIF_ALL;
GetScrollInfo(hWnd,SB_VERT,&si);
switch(LOWORD(wParam)){
case SB_LINUP:
si.nPos--;
break;
case SB_LINEDOWN:
si.nPos++;
break;
case SB_PAGEUP:
si.nPos-=si.nPage;
break;
case SB_PAGEDOWN:
si.nPos+=si.nPage;
break;
case SB_THUMBTRACK:
si.nPos=si.nTrackPos;
break;
}
si.fMask-SIF_POS;
SetScrollInfo(hWnd,SB_VERT,&si,TRUE);
InvalidateRect(hWnd,NULL,TRUE);
return 0;
}
//让图片滚动
在BitBlt之前。
int nXSrc=0,nYSrc=0;
SCROLLINFO si;
si.cbSize=sizeof(si);
si.fMask=SIF_POS;
if(GetScrollInfo(hWnd,SB_HORZ,&si))
nXSrc=si.nPos;
if(GetScrollInfo(hWnd,SB_VERT,&si))
nYSrc=si.nPos;
把这两个参数放入BitBlt中的截图位置。
窗口会闪的原因:
画背景和帖图的过程都被用户看到了。
把这个过程放到内存当中来做,然后 一次呈现到窗口中来,便不会看到闪了。
将刷子置为空
wcex.hbrBackground=(HBRUSH)GetStockObject(HOLLOW_BRUSH);
case WM_PAINT:
HDC hdcMem=CreateCompatibleDC(hDC);
HGDIOBJ hbmpOld=SelectObject(hdcMem,CreateCompatibleBitmap(hDC,sizeClient.cx,sizeClient.cy));
RECT rcClient={0,0,sizeClient.cx,sizeClient.cy};
FillRect(hdcMem,&rcClient,GetSysColorBrush(COLOR_APPWORKSPACE));
然后贴图贴到内存中。BitBlt
最后将内存中的用到窗口中
Bitblt(hDC,0,0,sizeClient.cx,sizeClient.cy,hdcMem,0,0,SRCCOPY);
DeleteObject(SelectObject(hdcMem,hbmpOld));
DeleteDC(hdcMem);
添加一个支持滚轮的效果:
case WM_MOUSEWHEEL:{
SCROLLINFO si;
si.cbSize=sizeof9si);
si.fMask=SIF_POS;
if(LOWORD(wParam)&MK_CONTRoL)
{
GetScrollInfo(hWnd,SB_HORZ,&si);
si.nPos-=(short)HIWORD(wParam)/12;
SetScrollInfo9hWnd,SB_HORZ,&si,TRUE);
}
else{
GetScrollInfo(hWnd,SB_VERT,&si);
//带上short才会有正负之分
si.nPos-=(short)HIWORD(wParam)/12;
SetScrollInfo(hWnd,SB_VERT,&si,TRUE);
}
InvalidateRect(hWnd,NULL,TRUE);
return 0;
}




二.组合框
::编辑框和列表框的组合。
1.分类
风格:CBS_SIMPLE--简单组合框(可编辑)
CBS_DROPDOWN---下拉组合框(要编辑)
CBS_DROPDOWNLIST--下拉列表组合框(不可编辑)
2.创建:
类名:COMBOBOX
工程名WinCombo
#define IDC_COMBO_SIMPLE 4001
#define IDC_COMBO_DROPDOwn 4002
#define IDC_COMBO_DrOPDOWNLIST 4003
static HWND hwndSimple=NULL,hwndDropdown=NULL,hwndDropdownList=NULL;
case WM_CREATE:
int x=4,y=4;
//简单风格
hwndSimple=CreateWindowEx(0,"COMBOBOX",NULL,WS_CHILD|WS_VISIBLE|CBX_SIMPLE|WS_VSCROLL,x,y,200,250,hWnd,(HMENU)IDC_COMBO_SIMPLE,g_hInstance,NULL);
//下拉风格
hwndSimple=CreateWindowEx(0,"COMBOBOX",NULL,WS_CHILD|WS_VISIBLE|CBX_DROPDOWN|WS_VSCROLL,x+=204,y,200,250,hWnd,(HMENU)IDC_COMBO_DROPDOWN,g_hInstance,NULL);
//下拉列表风格
hwndSimple=CreateWindowEx(0,"COMBOBOX",NULL,WS_CHILD|WS_VISIBLE|CBX_DROPDOWNLIST|WS_VSCROLL,x,y,200,250,hWnd,(HMENU)IDC_COMBO_DROPDOWNLIST,g_hInstance,NULL);
return 0;
break;


3.添加选项
窗口消息
CB_ADDSTRING--追加
wParam=0
lParam=字符串指针
CB_INSERTSTRING--插入
wParam--在此之前插入,从0开始
lParam-字符串指针


case WM_COMMAND:
switch(LOWORD(wParam)){
case IDM_COMBOBOX_ADD:{
for(int i=0;i<100,i++)
{
CHAR szItem[256];
sprintf(szItem,"Item %d",i);
SendMessage(hwndSimple,CB_ADDSTRING,0,(LPARAM)szItem);
SendMessage(hwndDropdown,CB_ADDSTRING,0,(LPARAM)szItem);
SendMessage(hwndDropdownList,CB_ADDSTRING,0,(LPARAM)szItem);
}
return 0;
}
}
4.获取/设置当前选择
窗口消息:
CB_GETCURSEL--获取当前选择项,SendMessage返回当前选择项的索引,无选择返回CB_ERR(-1)
wParam-0
lParam-0
CB_SETCURSEL--设置当前选择项
wParam--选择索引
lParam-0
//设置当前选择项
SendMessage(hwndSimple,CB_SETCURSEL,10,0);
SendMessage(hwndDropdown,CB_SETCURSEL,20,0);
SendMessage(hwndDropdownList,CB_SETCURSEL,30,0);
5.删除选项
CB_DELETESTRING---删除指定选项
wParam--选项索引
lParam--0
CB_RESETCONTENT-删除所有选项
wParam-0
lParam-0
//删除选项
case IDM_COMBOBOX_CLEAR:
SendMessage(hwndSimple,CB_RESETCONTENT,0,0);
SendMessage(hwndDropdown,CB_RESETCONTENT,0,0);
SendMessage(hwndDropdownList,CB_RESETCONTENT,0,0);
//删除当前选择的那一项
int nSelect=CB_ERR;
if((nSelect=SendMessage(hwndSimple,CB_GETCURSEL,0,0))!=CB_ERR)
SendMessage(hwndSimple,CB_DELETESTRING,nSelect,0);
return 0;
6.查找匹配的选项
窗口消息
CB_FINDSTRING--非精确匹配,SendMessage返回匹配选项的索引,没有匹配返回CB_ERR
wParam--查找起点的前一个选项索引
lParam--匹配字符串指针
CB_FINDSTRINGEXACT--精确匹配,与大小写无关
wParam--查找起点的前一个选项索引
lParam--匹配字符串指针
CB_SELECTSTRING--非精确匹配,同时选中匹配项
wParam--查找起点的前一个选项
lParam-匹配字符串指针
//查找
case IDM_COMBObox_FIND:
int nFind=CB_ERR;
if(SendMessage(hwndSimple,CB_FINDSTRING,-1,(LPARAM)"Item"))==CB_ERR)
MessageBox(hWnd,"找不到匹配选项",g_pszAppName,MB_OK);
else
CHAR szText[256];
sprintf(szText,"%d",nFind);
MessageBox(hWnd,szText,"SIMPLE",MB_OK);
7.获取选项内容
窗口消息:
CB_GETLBTEXTLEN--获取选项字符串长度,SendMessage返回,失败返回CB_ERR
wParam--选项索引
lParam--0
CB_GETLBTEXT--获取选项字符串
wParam--选项索引
lParam--缓冲区指针
注意:对于SIMPLE和DROPDOWN组合框编辑框中的文本,通过WM_GETTEXTLENGTH/WM_GETTEXT消息获取。


//
case IDM_COMBOBOX_TEXT:{
int nSelect=CB_ERR;
if((nSelect=SendMessage(hwndSimple,CB_GETCURSEL,0,0)!=CB_ERR){
int nLen=CB_ERR;
if((nLen=SendMessage(hwndSimple,CB_GETLBTEXTLEN,nSelect,0))!=CB_ERR){
LPSTR pszText=(LPSTR)malloc((nLen+1)*sizeof(CHAR));
SendMessage(hwndSimple,CB_GETLBTEXT,nSelect,pszText);
MessageBox(hWnd,psztext,"simple",MB_OK);
free(pszText);
}
///
int nLen=SendMessage(hwndSimple,WM_GETTEXTLENGTH,0,0);
if(nLen){
LPSTR pszText=(LPSTR)malloc((nLen+1)*sizeof(CHAR));
SendMessage(hwndSiple,WM_GETTEXT,nLen+1,(LPARAM)pszText);
MessageBox(hWnd,pszText,"SIMPLE-EDIT",MB_OK);
free(pszText);


8.设置/获取选项的附加数据
CB_SETITEMDATA--设置选项附加数据
wParam--选项索引
lParam--附加数据
CB_GETITEMDATA--获取选项附加数据,通过SendMessage返回
wParam-选项索引
lParam--0
/
SendMessage(hwndSimple,CB_SETITEMDATA,i,i+1000);
9.目录和文件的显示
CB_DIR在组合框中显示指定路径下的文件和目录
wParam--文件类型
lParam--路径字符串指针
wParam可取以下值的位域:
DDL_ARCHIVE--普通文件
DDL_DIRECTORY--目录
DDL_DRIVES----驱动文件
DDL_SYSTEM---系统文件 
DDL_HIDDEN--隐藏文件
DDL_READONLY--只读文件
DDL_EXCLUSIVE--只包含指定属性的文件

case IDM_COMBOBOX_DIR:
SendMessage(hwndSimple,CB_DIR,DDL_ARCHIVE,(LPARAM)"C:/WINDOWS/*.*");
SendMessage(hwndSimple,CB_DIR,DDL_DIRECTORY|DDL_EXCLUSIVE,(LPARAM)"C:/WINDOWS/*.*");
return 0;


10.通知消息
CBN_SELCHANGE--当前选择项发生变化
CBN_EDITCHANGE--编辑框的内容发生变化,仅对SIMPLE/DROPDOWN
case IDC_COMBo_SIMPLE:
switch(HIWORD(wParam)){
case CBN_SELCHANGE:
if(bSync&&(nSelect=SendMessage(hwndSimple,CB_GETCURSEL,0,0))!=cB_ERR){
SendMessage(hwndDropdown,CB_SETCURSEL,nSelect,0);
SendMessage(hwndDropdownList,CB_SETCURSEL,nSelect,0);
}
三列表框
1.分类
单列列表框
多列列表框
2.创建
LISTBOX
3.添加
LB_ADDSTRING
LB_INSERTSTRING
4.删除选项
LB_DELETESTRING
LB_RESETCONTENT
5.获取/设置当前选择项
LB_GETCURSEL
LB_SETCURSEL
6.查找匹配的选项
LB_FINDSTRING
LB_FINDSTRINGEXACT
LB_SELECTSTRING
7.获取选项内容
LB_GETTEXTLEN
LB_GETTEXT
8.目录显示
LB_DIR
9.设置/获取附加数据
LB_SETITEMDATA
LB_GETITEMDATA
10. 通知消息
LBN_SELCHANGE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值