滚动位图示例

【勇芳软件工作室】汉化HomePreviousNext

以下示例使用户能够将屏幕内容捕获到位图中,并滚动客户端区域中的位图。

HDC hdc;

PAINTSTRUCT ps;

SCROLLINFO si;

/ * BitBlt需要这些变量。*/

static HDC hdcWin; /* window DC */

static HDC hdcScreen; /* DC for entire screen */

static HDC hdcScreenCompat; /* memory DC for screen */

static HBITMAP hbmpCompat; /* bitmap handle for old DC */

static BITMAP bmp; /* bitmap data structure */

static BOOL fBlt; /* TRUE if BitBlt occurred */

static BOOL fScroll; /* TRUE if scrolling occurred */

static BOOL fSize; / * TRUE if fBlt & WM_SIZE * /

/ *这些变量是水平滚动所必需的。*/

static int xMinScroll; /* minimum horizontal scroll value */

static int xCurrentScroll; /* current horizontal scroll value */

static int xMaxScroll; /* maximum horizontal scroll value */

/ *垂直滚动需要这些变量。*/

static int yMinScroll; /* minimum vertical scroll value */

static int yCurrentScroll; /* current vertical scroll value */

static int yMaxScroll; /* maximum vertical scroll value */

开关(uMsg){

case WM_CREATE:

/*

*为整体创建一个正常的DC和一个内存DC

*屏幕。正常的DC提供了一个快照

*屏幕内容。内存DC保留这个的副本

*相关位图中的快照。

*/

hdcScreen = CreateDC("DISPLAY", (LPCSTR) NULL,

(LPCSTR) NULL, (CONST DEVMODE *) NULL);

hdcScreenCompat = CreateCompatibleDC(hdcScreen);

/*

*检索与该关联的位图的度量

*常规设备上下文。

*/

bmp.bmBitsPixel =

(BYTE) GetDeviceCaps(hdcScreen, BITSPIXEL);

bmp.bmPlanes = (BYTE) GetDeviceCaps(hdcScreen, PLANES);

bmp.bmWidth = GetDeviceCaps(hdcScreen, HORZRES);

bmp.bmHeight = GetDeviceCaps(hdcScreen, VERTRES);

/ *宽度必须是字节对齐。*/

bmp.bmWidthBytes = ((bmp.bmWidth + 15) &~15)/8;

/ *为兼容DC创建位图。*/

hbmpCompat = CreateBitmap(bmp.bmWidth, bmp.bmHeight,

bmp.bmPlanes, bmp.bmBitsPixel, (CONST VOID *) NULL);

/ *选择兼容的DC的位图。*/

SelectObject(hdcScreenCompat, hbmpCompat);

/ *初始化标志。*/

fBlt = FALSE;

fScroll = FALSE;

fSize = FALSE;

/ *初始化水平滚动变量。*/

xMinScroll = 0;

xCurrentScroll = 0;

xMaxScroll = 0;

/ *初始化垂直滚动变量。*/

yMinScroll = 0;

yCurrentScroll = 0;

yMaxScroll = 0;

break;

case WM_SIZE: {

int xNewSize;

int yNewSize;

xNewSize = LOWORD(lParam);

yNewSize = HIWORD(lParam);

if(fBlt)

fSize = TRUE;

/*

*水平滚动范围由...定义

*(bitmap_width) - (client_width)。当前水平

*滚动值保持在水平滚动范围内。

*/

xMaxScroll = max(bmp.bmWidth-xNewSize, 0);

xCurrentScroll = min(xCurrentScroll, xMaxScroll);

si.cbSize = sizeof(si);

si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;

si.nMin = xMinScroll;

si.nMax = xMaxScroll;

si.nPage = xNewSize;

si.nPos = xCurrentScroll;

SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);

/*

*垂直滚动范围由...定义

*(bitmap_height) - (client_height)。当前垂直

*滚动值保持在垂直滚动范围内。

*/

yMaxScroll = max(bmp.bmHeight - yNewSize, 0);

yCurrentScroll = min(yCurrentScroll, yMaxScroll);

si.cbSize = sizeof(si);

si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;

si.nMin = yMinScroll;

si.nMax = yMaxScroll;

si.nPage = yNewSize;

si.nPos = yCurrentScroll;

SetScrollInfo(hwnd, SB_VERT, &si, TRUE);

}

break;

case WM_PAINT: {

PRECT prect;

hdc = BeginPaint(hwnd, &ps);

/*

*如果窗口已经被调整大小,并且用户有

*捕获屏幕,使用以下调用

* BitBlt绘制窗口的客户区。

*/

if(fSize){

BitBlt(ps.hdc,

0, 0,

bmp.bmWidth,bmp.bmHeight,

hdcScreenCompat,

xCurrentScroll,yCurrentScroll,

SRCCOPY);

fSize = FALSE;

}

/*

*如果滚动发生,请使用以下调用

* BitBlt绘制无效矩形。

*

*这个矩形的坐标是在

* RECT结构,其中prect点。

*

*请注意,有必要增加第七

*参数(prect- >左)由xCurrentScroll和

*第八个参数(prect- > top)由yCurrentScroll在

*从源位图映射正确的像素。

*/

if(fScroll){

prect = &ps.rcPaint;

BitBlt(ps.hdc,

prect- > left,prect- > top,

(prect- > right - prect- >左),

(prect- > bottom-prect- > top),

hdcScreenCompat,

prect- > left + xCurrentScroll,

prect- > top + yCurrentScroll,

SRCCOPY);

fScroll = FALSE;

}

EndPaint(hwnd, &ps);

}

break;

case WM_HSCROLL: {

int xDelta; /* xDelta = new_pos - current_pos */

int xNewPos; /* new position */

int yDelta = 0;

开关(LOWORD(wParam)){

/ *用户点击滚动框左侧的轴。*/

case SB_PAGEUP:

xNewPos = xCurrentScroll - 50;

break;

/ *用户点击滚动框右侧的轴。*/

case SB_PAGEDOWN:

xNewPos = xCurrentScroll + 50;

break;

/ *用户点击左箭头。*/

case SB_LINEUP:

xNewPos = xCurrentScroll - 5;

break;

/ *用户点击右箭头。*/

case SB_LINEDOWN:

xNewPos = xCurrentScroll + 5;

break;

/ *用户拖动滚动框。*/

case SB_THUMBPOSITION:

xNewPos = HIWORD(wParam);

break;

默认:

xNewPos = xCurrentScroll;

}

/ *新位置必须介于0和屏幕宽度之间。*/

xNewPos = max(0, xNewPos);

xNewPos = min(xMaxScroll, xNewPos);

/ *如果当前位置不变,请不要滚动。* /

if (xNewPos == xCurrentScroll)

break;

/ *将滚动标志设置为TRUE。*/

fScroll = TRUE;

/ *确定滚动量(以像素为单位)。*/

xDelta = xNewPos - xCurrentScroll;

/ *重置当前滚动位置。*/

xCurrentScroll = xNewPos;

/*

*滚动窗口。(系统重绘大部分

* client area when ScrollWindowEx is called; however, it is

*必须调用UpdateWindow才能重新绘制

*无效的像素矩形。)

*/

ScrollWindowEx(hwnd,-xDelta,-yDelta,(CONST RECT *)NULL,

(CONST RECT *) NULL, (HRGN) NULL, (LPRECT) NULL,

SW_INVALIDATE);

UpdateWindow(hwnd);

/ *重置滚动条。*/

si.cbSize = sizeof(si);

si.fMask = SIF_POS;

si.nPos = xCurrentScroll;

SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);

}

break;

case WM_VSCROLL: {

int xDelta = 0;

int yDelta; /* yDelta = new_pos - current_pos */

int yNewPos; /* new position */

开关(LOWORD(wParam)){

/ *用户点击滚动框上方的轴。*/

case SB_PAGEUP:

yNewPos = yCurrentScroll - 50;

break;

/ *用户点击滚动条下方的轴。*/

case SB_PAGEDOWN:

yNewPos = yCurrentScroll + 50;

break;

/ *用户点击顶部箭头。*/

case SB_LINEUP:

yNewPos = yCurrentScroll - 5;

break;

/ *用户点击底部箭头。*/

case SB_LINEDOWN:

yNewPos = yCurrentScroll + 5;

break;

/ *用户拖动滚动框。*/

case SB_THUMBPOSITION:

yNewPos = HIWORD(wParam);

break;

默认:

yNewPos = yCurrentScroll;

}

/ *新位置必须在0和屏幕高度之间。*/

yNewPos = max(0, yNewPos);

yNewPos = min(yMaxScroll, yNewPos);

/ *如果当前位置不变,请不要滚动。* /

if (yNewPos == yCurrentScroll)

break;

/ *将滚动标志设置为TRUE。*/

fScroll = TRUE;

/ *确定滚动量(以像素为单位)。*/

yDelta = yNewPos - yCurrentScroll;

/ *重置当前滚动位置。*/

yCurrentScroll = yNewPos;

/*

*滚动窗口。(系统重绘大部分

* client area when ScrollWindowEx is called; however, it is

*必须调用UpdateWindow才能重新绘制

*无效的像素矩形。)

*/

ScrollWindowEx(hwnd,-xDelta,-yDelta,(CONST RECT *)NULL,

(CONST RECT *) NULL, (HRGN) NULL, (LPRECT) NULL,

SW_INVALIDATE);

UpdateWindow(hwnd);

/ *重置滚动条。*/

si.cbSize = sizeof(si);

si.fMask = SIF_POS;

si.nPos = yCurrentScroll;

SetScrollInfo(hwnd, SB_VERT, &si, TRUE);

}

break;

case WM_COMMAND: /* uMsg: command from app. menu */

开关(wParam){

case IDM_STC:

/*

*复制当前屏幕的内容

*进入兼容DC。

*/

BitBlt(hdcScreenCompat,0,0,bmp.bmWidth,

bmp.bmHeight, hdcScreen, 0, 0, SRCCOPY);

/*

*将兼容DC复制到客户端区域。

*/

hdcWin = GetDC(hwnd);

BitBlt(hdcWin,0,0,bmp.bmWidth,bmp.bmHeight,

hdcScreenCompat, 0, 0, SRCCOPY);

ReleaseDC(hwnd, hdcWin);

fBlt = TRUE;

break;

默认:

return(DefWindowProc(hwnd,uMsg,

wParam, lParam));

}

break;