So I've been stuck with this image resizing problem for a while: The program displays an image and then resizes it according to the size provided by the user when they drag the border, rather than clipping the image when the border is dragged inward or leaving it as it is when dragged outward.
I used a Display Window algorithm in the main WinAPI, and provided the declaration of an instance of the scaling algorithm in WM_PAINT.
I have to link to the scaling algorithm from a separate class from a separate file in the same project, which I've included in the header (#include"scaling.h"). After scaling the image I've called the display to the window again, but there aren't any changes in the size after dragging the border. What changes would I have to make to the code?
#include <windows.h>
#include <windows.h>
#include <tchar.h>
#include "scaling.h"
HBITMAP hBitmap;
HDC localDC;
HBITMAP hOld;
BITMAP qB;
HDC hDC; // Handle (virtual memory pointer) to drawing characteristics
RECT rect;
PAINTSTRUCT ps;
HDC MemDC;
HBITMAP bmp;
BITMAP bm;
LRESULT CALLBACK fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam){
switch(msg){
case WM_CREATE:{
//MessageBox(hwnd,_T("Window Procedure Received WM_CREATE Message!"),_T("Message Report!"),MB_OK);
return 0;
}
case WM_LBUTTONDOWN: {
//MessageBox(hwnd,_T("Window Procedure Received WM_LBUTTONDOWN Message!"),_T("Message Report!"),MB_OK);
return 0;
}
case WM_PAINT: { //At program start up the whole window is invalid so must be drawn.
//TCHAR tmpText[]=_T("TempText");
PAINTSTRUCT ps;
hDC = BeginPaint(hwnd,&ps);
BOOL qRetBlit = ::BitBlt(hDC,0,0,qB.bmWidth,qB.bmHeight,localDC,0,0,SRCCOPY);
::GetClientRect(hwnd, &rect);
// Create a memory device compatible with the above DC variable
MemDC = CreateCompatibleDC(hDC);
// Select the new bitmap
SelectObject(MemDC, hBitmap);
GetObject(hBitmap, sizeof(bm), &bm);
int w2,h2;
if(GetClientRect(hwnd, &rect)) //In order to obtain the current window's parameters
{
w2 = rect.right - rect.left;
h2 = rect.bottom - rect.top;
}
BYTE *pixels_old = (BYTE *)qB.bmBits;
scaling sc;
BYTE *pixels = sc.resizePixels(pixels_old, qB.bmWidth, qB.bmHeight, w2, h2);
qB.bmBits = pixels;
MemDC = CreateCompatibleDC(hDC);
SelectObject(MemDC, &qB);
hDC = BeginPaint(hwnd,&ps);
qRetBlit = ::BitBlt(hDC,w2,h2,qB.bmWidth,qB.bmHeight,localDC,0,0,SRCCOPY);
delete []pixels;
// Return Drawing Context To Original State
EndPaint(hwnd, &ps);
return 0;
}
case WM_DESTROY: {
::SelectObject(localDC,hOld);
::DeleteDC(localDC);
::DeleteObject(hBitmap);
PostQuitMessage(0);
return 0;
}
}
return (DefWindowProc(hwnd, msg, wParam, lParam));
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int iShow){
TCHAR szClassName[]=_T("Name");
WNDCLASSEX wc;
MSG messages;
HWND hWnd;
wc.lpszClassName = szClassName;
wc.lpfnWndProc = fnWndProc;
wc.cbSize = sizeof (WNDCLASSEX);
wc.style = 0;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hInstance = hInstance;
wc.hIconSm = 0; //LoadIcon(wc.hInstance, MAKEINTRESOURCE(IDI_SMALL));
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW;
wc.cbWndExtra = 0;
wc.cbClsExtra = 0;
wc.lpszMenuName = NULL;
RegisterClassEx(&wc);
hBitmap = (HBITMAP)::LoadImage(NULL, _T("D:\\Chrysanthemum.bmp"),IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
GetObject(reinterpret_cast<HGDIOBJ>(hBitmap),sizeof(BITMAP),reinterpret_cast<LPVOID>(&qB));
localDC = ::CreateCompatibleDC(hDC);
hOld = (HBITMAP)::SelectObject(localDC,hBitmap);
hWnd = CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,0,0,qB.bmWidth,qB.bmHeight,HWND_DESKTOP,0,hInstance,0);
ShowWindow(hWnd,iShow);
while(GetMessage(&messages,NULL,0,0)){
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return (int)messages.wParam;
}
The scaling algorithm from "Scaling.h" is as follows: (nearest neighbour)
#include <iostream>
class scaling{
public:
BYTE* resizePixels(BYTE* pixels,int w1,int h1,int w2,int h2)
{
BYTE* retval = new BYTE[w2*h2] ;
// EDIT: added +1 to remedy an early rounding problem
int x_ratio = (int)((w1<<16)/w2) +1;
int y_ratio = (int)((h1<<16)/h2) +1;
//int x_ratio = (int)((w1<<16)/w2) ;
//int y_ratio = (int)((h1<<16)/h2) ;
int x2, y2 ;
for (int i=0;i<h2;i++) {
for (int j=0;j<w2;j++) {
x2 = ((j*x_ratio)>>16) ;
y2 = ((i*y_ratio)>>16) ;
retval[(i*w2)+j] = pixels[(y2*w1)+x2] ;
}
}
return retval;
}
};
Thanks in advance!