Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu bölümde, kullanıcının bitmap kaydırmasını sağlamak için uygulamanın ana pencere prosedüründe yapabileceğiniz değişiklikler açıklanmaktadır.
Örnek, ekran içeriğini bit eşlem olarak kopyalayan ve bit eşlemi istemci alanında görüntüleyen bir menü öğesi içerir. Örnek, kullanıcının bit eşlemi yatay ve dikey olarak kaydırabilmesi için kaydırma çubukları tarafından oluşturulan WM_HSCROLL ve WM_VSCROLL iletilerini de işler. Kaydırılan metin örneğinden farklı olarak bit eşlem örneği, istemci alanının geçersiz bölümünü çizmek için BitBlt işlevini çalıştırır.
Bilmeniz gerekenler
Teknolojileri
Önkoşullar
- C/C++
- Windows Kullanıcı Arayüzü Programlama
Talimatlar
WM_CREATE İletisini İşleme
WM_CREATE mesajı işlendiğinde, kaydırma için gerekli değişkenler başlatılır. Uyumlu bir cihaz bağlamı (DC) oluşturmak için CreateCompatibleDC işlevini, bit eşlem oluşturmak için CreateBitmap işlevini ve DC için bit eşlemi seçmek üzere SelectObjectişlevinikullanın. Uyumlu bir DC'nin bellek DC olarak da bilindiğini unutmayın.
Görüntü cihazıyla ilgili cihaza özgü bilgiler alınır. Örnekte olduğu gibi ekran için uyumlu bir DC oluşturulduysa, bu bilgileri almak için GetDeviceCapsişlevinikullanın. Bilgiler piksel başına bitişik renk bitlerinin sayısını, renk düzlemlerinin sayısını ve DC'nin yüksekliğini ve genişliğini içerir.
WM_SIZE İletisini İşleme
WM_SIZE iletisinin işlenmesi için kaydırma aralığının ve konumunun, istemci alanının ve görüntülenecek bit eşlem alanının boyutlarını yansıtacak şekilde ayarlanması gerekir.
SetScrollInfo işlevi en düşük ve en yüksek konum değerlerini, sayfa boyutunu ve kaydırma çubuğunun kaydırma konumunu ayarlar.
WM_HSCROLL ve WM_VSCROLL İletilerini İşleme
WM_HSCROLL ve WM_VSCROLL iletileri işlendiğinde kaydırma çubuğu istek kodu incelenir ve kaydırma konumu kullanıcının kaydırma eylemini yansıtan yeni bir değere ayarlanır. Kaydırma konumu kaydırma aralığı içindeyse, ScrollWindow işlevi kullanılarak pencere yeni konuma kaydırılır. Kaydırma kutusunun konumu daha sonra SetScrollInfo işlevi kullanılarak ayarlanır.
Bir pencere kaydırıldıktan sonra istemci alanının bir bölümü geçersiz hale getirilir. Geçersiz bölgenin güncelleştirildiğinden emin olmak için UpdateWindow işlevini kullanarak bir WM_PAINT iletisi oluşturun. WM_PAINT iletisini işlerken, uygulamanın istemci alanının alt kısmındaki geçersiz bölgeyi yeniden boyaması gerekir. İstemci alanını kaydırırken veya yeniden boyutlandırırken, örnek bit eşleminin uygun bölümünü istemci alanının geçersiz bölümüne kopyalamak için BitBlt işlevini kullanır.
Bitmap Kaydırma Örneği
Aşağıdaki örnek, kullanıcının ekran içeriğini bit eşlem halinde yakalamasını ve istemci alanındaki bit eşlemi kaydırmasını sağlar. Kullanıcı istemci alanına sağ tıkladığında ekran içeriği yakalanır.
LRESULT CALLBACK MyBitmapWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
SCROLLINFO si;
// These variables are required by 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 to 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
// These variables are required for horizontal scrolling.
static int xMinScroll; // minimum horizontal scroll value
static int xCurrentScroll; // current horizontal scroll value
static int xMaxScroll; // maximum horizontal scroll value
// These variables are required for vertical scrolling.
static int yMinScroll; // minimum vertical scroll value
static int yCurrentScroll; // current vertical scroll value
static int yMaxScroll; // maximum vertical scroll value
switch (uMsg)
{
case WM_CREATE:
// Create a normal DC and a memory DC for the entire
// screen. The normal DC provides a snapshot of the
// screen contents. The memory DC keeps a copy of this
// snapshot in the associated bitmap.
hdcScreen = CreateDC(L"DISPLAY", (PCTSTR) NULL,
(PCTSTR) NULL, (CONST DEVMODE *) NULL);
hdcScreenCompat = CreateCompatibleDC(hdcScreen);
// Retrieve the metrics for the bitmap associated with the
// regular device context.
bmp.bmBitsPixel =
(BYTE) GetDeviceCaps(hdcScreen, BITSPIXEL);
bmp.bmPlanes = (BYTE) GetDeviceCaps(hdcScreen, PLANES);
bmp.bmWidth = GetDeviceCaps(hdcScreen, HORZRES);
bmp.bmHeight = GetDeviceCaps(hdcScreen, VERTRES);
// The width must be byte-aligned.
bmp.bmWidthBytes = ((bmp.bmWidth + 15) &~15)/8;
// Create a bitmap for the compatible DC.
hbmpCompat = CreateBitmap(bmp.bmWidth, bmp.bmHeight,
bmp.bmPlanes, bmp.bmBitsPixel, (CONST VOID *) NULL);
// Select the bitmap for the compatible DC.
SelectObject(hdcScreenCompat, hbmpCompat);
// Initialize the flags.
fBlt = FALSE;
fScroll = FALSE;
fSize = FALSE;
// Initialize the horizontal scrolling variables.
xMinScroll = 0;
xCurrentScroll = 0;
xMaxScroll = 0;
// Initialize the vertical scrolling variables.
yMinScroll = 0;
yCurrentScroll = 0;
yMaxScroll = 0;
break;
case WM_SIZE:
{
int xNewSize;
int yNewSize;
xNewSize = LOWORD(lParam);
yNewSize = HIWORD(lParam);
if (fBlt)
fSize = TRUE;
// The horizontal scrolling range is defined by
// (bitmap_width) - (client_width). The current horizontal
// scroll value remains within the horizontal scrolling range.
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 = bmp.bmWidth;
si.nPage = xNewSize;
si.nPos = xCurrentScroll;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
// The vertical scrolling range is defined by
// (bitmap_height) - (client_height). The current vertical
// scroll value remains within the vertical scrolling range.
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 = bmp.bmHeight;
si.nPage = yNewSize;
si.nPos = yCurrentScroll;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
break;
}
case WM_PAINT:
{
PRECT prect;
hdc = BeginPaint(hwnd, &ps);
// If the window has been resized and the user has
// captured the screen, use the following call to
// BitBlt to paint the window's client area.
if (fSize)
{
BitBlt(ps.hdc,
0, 0,
bmp.bmWidth, bmp.bmHeight,
hdcScreenCompat,
xCurrentScroll, yCurrentScroll,
SRCCOPY);
fSize = FALSE;
}
// If scrolling has occurred, use the following call to
// BitBlt to paint the invalid rectangle.
//
// The coordinates of this rectangle are specified in the
// RECT structure to which prect points.
//
// Note that it is necessary to increment the seventh
// argument (prect->left) by xCurrentScroll and the
// eighth argument (prect->top) by yCurrentScroll in
// order to map the correct pixels from the source bitmap.
if (fScroll)
{
prect = &ps.rcPaint;
BitBlt(ps.hdc,
prect->left, prect->top,
(prect->right - prect->left),
(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;
switch (LOWORD(wParam))
{
// User clicked the scroll bar shaft left of the scroll box.
case SB_PAGEUP:
xNewPos = xCurrentScroll - 50;
break;
// User clicked the scroll bar shaft right of the scroll box.
case SB_PAGEDOWN:
xNewPos = xCurrentScroll + 50;
break;
// User clicked the left arrow.
case SB_LINEUP:
xNewPos = xCurrentScroll - 5;
break;
// User clicked the right arrow.
case SB_LINEDOWN:
xNewPos = xCurrentScroll + 5;
break;
// User dragged the scroll box.
case SB_THUMBPOSITION:
xNewPos = HIWORD(wParam);
break;
default:
xNewPos = xCurrentScroll;
}
// New position must be between 0 and the screen width.
xNewPos = max(0, xNewPos);
xNewPos = min(xMaxScroll, xNewPos);
// If the current position does not change, do not scroll.
if (xNewPos == xCurrentScroll)
break;
// Set the scroll flag to TRUE.
fScroll = TRUE;
// Determine the amount scrolled (in pixels).
xDelta = xNewPos - xCurrentScroll;
// Reset the current scroll position.
xCurrentScroll = xNewPos;
// Scroll the window. (The system repaints most of the
// client area when ScrollWindowEx is called; however, it is
// necessary to call UpdateWindow in order to repaint the
// rectangle of pixels that were invalidated.)
ScrollWindowEx(hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,
(CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL,
SW_INVALIDATE);
UpdateWindow(hwnd);
// Reset the scroll bar.
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
switch (LOWORD(wParam))
{
// User clicked the scroll bar shaft above the scroll box.
case SB_PAGEUP:
yNewPos = yCurrentScroll - 50;
break;
// User clicked the scroll bar shaft below the scroll box.
case SB_PAGEDOWN:
yNewPos = yCurrentScroll + 50;
break;
// User clicked the top arrow.
case SB_LINEUP:
yNewPos = yCurrentScroll - 5;
break;
// User clicked the bottom arrow.
case SB_LINEDOWN:
yNewPos = yCurrentScroll + 5;
break;
// User dragged the scroll box.
case SB_THUMBPOSITION:
yNewPos = HIWORD(wParam);
break;
default:
yNewPos = yCurrentScroll;
}
// New position must be between 0 and the screen height.
yNewPos = max(0, yNewPos);
yNewPos = min(yMaxScroll, yNewPos);
// If the current position does not change, do not scroll.
if (yNewPos == yCurrentScroll)
break;
// Set the scroll flag to TRUE.
fScroll = TRUE;
// Determine the amount scrolled (in pixels).
yDelta = yNewPos - yCurrentScroll;
// Reset the current scroll position.
yCurrentScroll = yNewPos;
// Scroll the window. (The system repaints most of the
// client area when ScrollWindowEx is called; however, it is
// necessary to call UpdateWindow in order to repaint the
// rectangle of pixels that were invalidated.)
ScrollWindowEx(hwnd, -xDelta, -yDelta, (CONST RECT *) NULL,
(CONST RECT *) NULL, (HRGN) NULL, (PRECT) NULL,
SW_INVALIDATE);
UpdateWindow(hwnd);
// Reset the scroll bar.
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = yCurrentScroll;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
break;
}
case WM_RBUTTONDOWN:
{
// Get the compatible DC of the client area.
hdcWin = GetDC(hwnd);
// Fill the client area to remove any existing contents.
RECT rect;
GetClientRect(hwnd, &rect);
FillRect(hdcWin, &rect, (HBRUSH)(COLOR_WINDOW+1));
// Copy the contents of the current screen
// into the compatible DC.
BitBlt(hdcScreenCompat, 0, 0, bmp.bmWidth,
bmp.bmHeight, hdcScreen, 0, 0, SRCCOPY);
// Copy the compatible DC to the client area.
BitBlt(hdcWin, 0, 0, bmp.bmWidth, bmp.bmHeight,
hdcScreenCompat, 0, 0, SRCCOPY);
ReleaseDC(hwnd, hdcWin);
fBlt = TRUE;
break;
}
case WM_DESTROY :
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, uMsg, wParam, lParam);
}
İlgili konular