How to make my win32 app show right mouse clicks - c++

This is what i Have so far.
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
GetClientRect (hwnd, &rect);
GetWindowRect(hwnd, &size);
width = size.right - size.left;
itoa(width, Swidth, 10);
height = size.bottom - size.top;
itoa(height, Sheight, 10);
itoa(rect.bottom, sBottom, 10);
itoa(rect.top, sTop, 10);
itoa(rect.left, sLeft, 10);
itoa(rect.right, sRight, 10);
TextOut(hdc, 0, 0, "Here is my width: ", 18);
TextOut(hdc, 125, 0, Swidth, 5);
TextOut(hdc, 175, 0, "Here is my height: ", 18);
TextOut(hdc, 300, 0, Sheight, 4);
TextOut(hdc, 0, 20, sBottom, strlen(sBottom));
TextOut(hdc, 50, 20, sTop, strlen(sTop));
TextOut(hdc, 100, 20, sRight, strlen(sRight));
TextOut(hdc, 150, 20, sLeft, strlen(sLeft));
TextOut(hdc, 0, 40, "Right Button Clicked: ", 23);
itoa(rightButtonClicked, SrightButtonClicked, 10);
TextOut(hdc, 150, 40, SrightButtonClicked, strlen(SrightButtonClicked));
if(rightButtonClicked > 20)
TextOut(hdc, 0, 60, SrightButtonClicked, strlen(SrightButtonClicked));
EndPaint (hwnd, &ps);
return 0;
case WM_LBUTTONDOWN:
return 0;
case WM_RBUTTONDOWN:
rightButtonClicked++;
return 0
Now I'm not sure what I"m doing wrong but I'm supposed to make it output the number of times I right click within the windows. The counter I have for rightButtonClicked incremetns but it won't display properly. Yes this is homework and I have researched the topic quite a bit so I'm looking for a little help.

Related

How can I calculate the height and width of a given text? OpenGL

I draw the text using this two functions: https://pastebin.com/JVc5xFFT
I draw the text - GlText(dc, "Test", ERGB{ 155, 179, 0 }, 5, 220);
I build a font to uint with this function
GLvoid BuildFont(HDC hDC, UINT* FontBase, int PointerWidth)
{
HFONT font;
HFONT oldfont;
*FontBase = glGenLists(96);
font = CreateFontW(-MulDiv(PointerWidth, GetDeviceCaps(hDC, LOGPIXELSY), 72),
0,
0,
0,
FW_BOLD,
FALSE,
FALSE,
FALSE,
ANSI_CHARSET,
OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS,
ANTIALIASED_QUALITY,
VARIABLE_PITCH | FF_SWISS,
L"Trebuchet MS");
oldfont = (HFONT)SelectObject(hDC, font);
wglUseFontBitmaps(hDC, 32, 96, *FontBase);
SelectObject(hDC, oldfont);
DeleteObject(font);
}
How can I find out the height and width of a given text?󠀡󠀡
󠀡󠀡
󠀡󠀡
Function for calculating(badly code. but working):
SIZE CalculateTextSize(HDC dc, std::string text) {
SIZE szi;
SelectObject(dc, Font);
SetTextCharacterExtra(dc, 1);
GetTextExtentPoint32A(dc, text.c_str(), strlen(text.c_str()), &szi);
szi.cx -= GetTextCharacterExtra(dc) * (strlen(text.c_str()) - 2);
szi.cy -= ((FontSize % 2) % 2 == 0) ? FontSize / 2 : (FontSize / 2) - 1;
return szi;
}

How to adjust window border size

I have a window, which I want it to behave like a toggle button. Once clicked it will add 4px border and clicking after will make the border disappear. I figured how to make the window behave like a toggle button using BS_PUSHLIKE and Button_SetCheck() but can't seem to figure out how to adjust the border size for this window.
Thanks to all who take their time to help
Maybe you can use MoveWindow to resize the window, and then draw the border yourself, like this,
Draw a borderless window first:
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
100, 100, 800, 600, nullptr, nullptr, hInstance, nullptr);
LONG lStyle = GetWindowLong(hWnd, GWL_STYLE);
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
SetWindowLong(hWnd, GWL_STYLE, lStyle);
Then handle the window border in the WM_LBUTTONDOWN message:
int num = 0;
case WM_LBUTTONDOWN:
{
RECT rcWind;
HDC dc = GetDC(hWnd);
GetWindowRect(hWnd, &rcWind);
if (num >= 0)
{
num--;
RECT rcClient;
MoveWindow(hWnd, rcWind.left - 4, rcWind.top - 4, 8 + rcWind.right - rcWind.left, 8 + rcWind.bottom - rcWind.top, TRUE);
GetClientRect(hWnd, &rcClient);
HPEN hPen = CreatePen(PS_SOLID, 4, RGB(255, 128, 1));
HGDIOBJ hOldPen = SelectObject(dc, hPen);
Rectangle(dc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
DeleteObject(hPen);
}
else if (num < 0)
{
MoveWindow(hWnd, rcWind.left + 4, rcWind.top + 4, rcWind.right - rcWind.left - 8, rcWind.bottom - rcWind.top - 8, TRUE);
num++;
}
}
break;

Draw with Windows API

I develop this program that works fine and draws some figures to the screen:
#include <Windows.h>
#include<windows.h>
#include<iostream>
using namespace std;
int main() {
cin.ignore();
//Get a console handle
HWND myconsole = GetConsoleWindow();
//Get a handle to device context
HDC mydc = GetDC(myconsole);
//Choose any color
COLORREF COLOR= RGB(255,255,255);
HPEN hBluePen = CreatePen(PS_SOLID, 1, COLOR);
HGDIOBJ hPen = SelectObject(mydc, hBluePen);
//Lines
MoveToEx(mydc, 10, 40, NULL);
LineTo(mydc, 44, 10);
LineTo(mydc, 78, 40);
//Rectangles
cin.ignore();
Rectangle(mydc, 16, 36, 72, 70);
Rectangle(mydc, 60, 80, 80, 90);
//Elipse
cin.ignore();
Ellipse(mydc, 40, 55, 48, 65);
ReleaseDC(myconsole, mydc);
cin.ignore();
return 0;
}
But when I resize or minimize the console all the drawed stuff disapear, someone could gave me an example of how this could be fixed?

Win32 confusing flicker

I have a function in which a bunch of stuff is drawn into an offscreen buffer. At the end of the function, it calls InvalidateRect. For some reason, sometimes it redraws halfway through the function, causing a flicker. Here's the code for the function:
// Side Info
HBITMAP side = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SIDEINFO));
hdcold = (HBITMAP)SelectObject(hbcmem, side);
BitBlt(hdcmem, 339, 26, 154, 300, hbcmem, 0, 0, SRCCOPY);
DrawLevelNumber(game.levelnumber);
if (color)
sprites = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_COLOR_SPRITES));
else sprites = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BLACKWHITE_SPRITES));
hdcold = (HBITMAP)SelectObject(hbcmem, sprites);
// Find x and y coordinate for the top left of the visible screen
int x = game.Player_x, y = game.Player_y, ypos = 0;
if (x < 4) x = 4;
if (x > 27) x = 27;
if (y < 4) y = 4;
if (y > 27) y = 27;
x -= 4;
y -= 4;
// Draw lower layer
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if (game.Layer_Two[x + i][y + j] != 0)
{
int xpos = game.get_pos(game.Layer_Two[x + i][y + j], ypos, false);
BitBlt(hdcmem, (i * 32) + 32, (j * 32) + 32, 32, 32, hbcmem, xpos, ypos, SRCCOPY);
}
}
}
// Draw upper layer
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
if ((game.Layer_Two[x + i][y + j] != 0 && game.Layer_One[x + i][y + j] >= 64 && game.Layer_One[x + i][y + j] <= 111))
{
int xpos = game.get_pos(game.Layer_One[x + i][y + j], ypos, true);
BitBlt(hdcmem, (i * 32) + 32, (j * 32) + 32, 32, 32, hbcmem, xpos + 96, ypos, SRCPAINT);
BitBlt(hdcmem, (i * 32) + 32, (j * 32) + 32, 32, 32, hbcmem, xpos, ypos, SRCAND);
} else {
int xpos = game.get_pos(game.Layer_One[x + i][y + j], ypos, false);
BitBlt(hdcmem, (i * 32) + 32, (j * 32) + 32, 32, 32, hbcmem, xpos, ypos, SRCCOPY);
}
}
}
// If it isn't started, show title
if (!game.started)
{
HDC tmphdc = CreateCompatibleDC(hdcmem);
HDC tmp = CreateCompatibleDC(tmphdc);
RECT rc;
GetClientRect(hWnd, &rc);
string str = game.leveltitle.substr(0, game.leveltitle.length() - 1) + "\nPassword: " + game.password;
TCHAR* tch = new TCHAR[str.length()];
mbstowcs_s(NULL, tch, _tcslen(tch), str.c_str(), str.length());
HFONT font = CreateFont(25, 0, 0, 0, FW_BOLD, false, false, false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, NULL);
SelectObject(tmp, font);
DrawText(tmp, tch, str.length(), &rc, DT_CALCRECT);
rc.right += 16;
HBITMAP tmpbm = CreateCompatibleBitmap(hdcmem, rc.right, rc.bottom);
HBITMAP tmpold = (HBITMAP)SelectObject(tmphdc, tmpbm);
HBRUSH hbr = CreateSolidBrush(RGB(255, 255, 255));
HPEN pen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
SelectObject(hdcmem, pen);
SelectObject(hdcmem, hbr);
Rectangle(hdcmem, 176 - (rc.right / 2), 243, 177 + (rc.right / 2), 248);
hbr = CreateSolidBrush(RGB(128, 128, 128));
pen = CreatePen(PS_SOLID, 1, RGB(128, 128, 128));
SelectObject(hdcmem, pen);
SelectObject(hdcmem, hbr);
Rectangle(hdcmem, 176 - (rc.right / 2), 294, 177 + (rc.right / 2), 299);
HBITMAP left = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_LEFT));
hdcold = (HBITMAP)SelectObject(hbcmem, left);
BitBlt(hdcmem, 176 - (rc.right / 2) - 4, 243, 4, 56, hbcmem, 0, 0, SRCCOPY);
HBITMAP right = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_RIGHT));
hdcold = (HBITMAP)SelectObject(hbcmem, right);
BitBlt(hdcmem, 176 + (rc.right / 2) + 1, 243, 4, 56, hbcmem, 0, 0, SRCCOPY);
SelectObject(tmphdc, font);
SetTextColor(tmphdc, RGB(255, 255, 0));
SetBkColor(tmphdc, RGB(0, 0, 0));
DrawText(tmphdc, tch, str.length(), &rc, DT_CENTER);
BITMAP structBitmapHeader;
memset( &structBitmapHeader, 0, sizeof(BITMAP) );
HGDIOBJ hBitmap = GetCurrentObject(tmphdc, OBJ_BITMAP);
GetObject(hBitmap, sizeof(BITMAP), &structBitmapHeader);
BitBlt(hdcmem, 176 - (rc.right / 2), 247, structBitmapHeader.bmWidth, structBitmapHeader.bmHeight, tmphdc, 0, 0, SRCCOPY);
}
// If paused
if (game.paused)
{
RECT rc;
rc.top = 32;
rc.left = 32;
rc.bottom = 330;
rc.right = 330;
BitBlt(hdcmem, 32, 32, 288, 288, NULL, 0, 0, BLACKNESS);
HFONT font = CreateFont(50, 0, 0, 0, FW_NORMAL, false, false, false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, NULL);
SelectObject(hdcmem, font);
SetTextColor(hdcmem, RGB(255, 0, 0));
SetBkColor(hdcmem, RGB(0, 0, 0));
DrawText(hdcmem, L"PAUSED", 6, &rc, (DT_CENTER + DT_SINGLELINE + DT_VCENTER));
}
nums = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_NUMBERS));
hdcold = (HBITMAP)SelectObject(hbcmem, nums);
for (int i = 100; i > 0; i /= 10) // Coins left
{
int tmp;
if (i == 100)
tmp = game.coinsleft / 100;
if (i == 10)
tmp = ((game.coinsleft % 100) - (game.coinsleft % 10)) / 10;
if (i == 1)
tmp = game.coinsleft % 10;
if (game.coinsleft < i && i > 1)
tmp = 10;
int ypos = game.get_num_pos(tmp, (game.coinsleft == 0));
BitBlt(hdcmem, 369 + ((3 - log10((double)i)) * 17), 215, 17, 23, hbcmem, 0, ypos, SRCCOPY);
if (i == 100)
tmp = game.timeleft / 100;
if (i == 10)
tmp = ((game.timeleft % 100) - (game.timeleft % 10)) / 10;
if (i == 1)
tmp = game.timeleft % 10;
if (game.timeleft < i && i > 1)
tmp = 10;
if (game.timelimit == 0)
tmp = 11;
ypos = game.get_num_pos(tmp, (game.timeleft < 16 || game.timelimit == 0));
BitBlt(hdcmem, 369 + ((3 - log10((double)i)) * 17), 125, 17, 23, hbcmem, 0, ypos, SRCCOPY);
}
if (game.onhint)
{
HBITMAP sidebg = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SIDEBG));
hdcold = (HBITMAP)SelectObject(hbcmem, sidebg);
BitBlt(hdcmem, 353, 165, 127, 146, hbcmem, 0, 0, SRCCOPY);
} else {
hdcold = (HBITMAP)SelectObject(hbcmem, sprites); // LOWER SIDE INFO
if (game.key1 > 0)
BitBlt(hdcmem, 352, 247, 32, 32, hbcmem, 192, 160, SRCCOPY);
else BitBlt(hdcmem, 352, 247, 32, 32, hbcmem, 0, 0, SRCCOPY);
if (game.key2 > 0)
BitBlt(hdcmem, 384, 247, 32, 32, hbcmem, 192, 128, SRCCOPY);
else BitBlt(hdcmem, 384, 247, 32, 32, hbcmem, 0, 0, SRCCOPY);
if (game.key3 > 0)
BitBlt(hdcmem, 416, 247, 32, 32, hbcmem, 192, 224, SRCCOPY);
else BitBlt(hdcmem, 416, 247, 32, 32, hbcmem, 0, 0, SRCCOPY);
if (game.key4)
BitBlt(hdcmem, 448, 247, 32, 32, hbcmem, 192, 192, SRCCOPY);
else BitBlt(hdcmem, 448, 247, 32, 32, hbcmem, 0, 0, SRCCOPY);
if (game.water)
BitBlt(hdcmem, 352, 279, 32, 32, hbcmem, 192, 256, SRCCOPY);
else BitBlt(hdcmem, 352, 279, 32, 32, hbcmem, 0, 0, SRCCOPY);
if (game.fire)
BitBlt(hdcmem, 384, 279, 32, 32, hbcmem, 192, 288, SRCCOPY);
else BitBlt(hdcmem, 384, 279, 32, 32, hbcmem, 0, 0, SRCCOPY);
if (game.ice)
BitBlt(hdcmem, 416, 279, 32, 32, hbcmem, 192, 320, SRCCOPY);
else BitBlt(hdcmem, 416, 279, 32, 32, hbcmem, 0, 0, SRCCOPY);
if (game.suction)
BitBlt(hdcmem, 448, 279, 32, 32, hbcmem, 192, 352, SRCCOPY);
else BitBlt(hdcmem, 448, 279, 32, 32, hbcmem, 0, 0, SRCCOPY);
}
RECT rc;
rc.left = 0;
rc.top = 0;
rc.right = 518;
rc.bottom = 401;
InvalidateRect(hWnd, &rc, false);
What is causing the flicker?
Ensure that you handle the WM_ERASEBKGND message and return TRUE, this will prevent the window base class from drawing the background.
Instead of calling InvalidateRect at the end of your drawing routine, place your drawing code inside a WM_PAINT message handler, this ensures your drawing code is called whenever the window is being repainted.

Win32 - why is nothing being drawn to the screen?

I'm trying to use an off-screen buffer so that I can keep track of changes to the screen before/after WM_PAINT and just copy them through one line in WM_PAINT. Here's some code I have to set up the graphics:
hdc = GetDC(hWnd);
hdcmem = CreateCompatibleDC(hdc);
hbcmem = CreateCompatibleDC(hdcmem);
// Load bitmaps
bg = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BACKGROUND));
side = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SIDEINFO));
mainCont = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_GAME_CONT));
if(bg == NULL || side == NULL || mainCont == NULL)
ThrowError("A bitmap failed to load.");
// Background
hdcold = (HBITMAP)SelectObject(hbcmem, bg);
BitBlt(hdcmem, 0, 0, 237, 196, hbcmem, 0, 0, SRCCOPY);
BitBlt(hdcmem, 237, 0, 237, 196, hbcmem, 0, 0, SRCCOPY);
BitBlt(hdcmem, 237 * 2, 0, 237, 196, hbcmem, 0, 0, SRCCOPY);
BitBlt(hdcmem, 0, 196, 237, 196, hbcmem, 0, 0, SRCCOPY);
BitBlt(hdcmem, 237, 196, 237, 196, hbcmem, 0, 0, SRCCOPY);
BitBlt(hdcmem, 237 * 2, 196, 237, 196, hbcmem, 0, 0, SRCCOPY);
// Side Info
hdcold = (HBITMAP)SelectObject(hbcmem, side);
BitBlt(hdcmem, 339, 26, 154, 300, hbcmem, 0, 0, SRCCOPY);
// Main Game Container
hdcold = (HBITMAP)SelectObject(hbcmem, mainCont);
BitBlt(hdcmem, 26, 26, 300, 300, hbcmem, 0, 0, SRCCOPY);
hdc, hdcmem, hbcmem, hdcold, bg, side, and mainCont are declared previously. Their scope includes everything in this file (including this code and the code in WM_PAINT).
Here's the code in WM_PAINT:
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
BitBlt(hdc, 0, 0, 518, 401, hdcmem, 0, 0, SRCCOPY);
EndPaint(hWnd, &ps);
For some reason, nothing is being drawn to the screen. I'm racking my brain trying to figure it out. A pointer in the right direction would be much appreciated.
Create a compatible bitmap for your memory device context first, then select that bitmap to the memory dc and it should work !
hdc = GetDC(hWnd); // used only to create compatibles.
hdcmem = CreateCompatibleDC(hdc);
hbcmem = CreateCompatibleDC(hdc);
// Create client-area-sized compatible bitmap.
RECT rc;
GetClientRect(hWnd, &rc);
HBITMAP hbm_memdc = CreateComptibleBitmap(hdc, rc.right, rc.bottom);
HBITMAP hbm_memdc_old = (HBITMAP)SelectObject(hdcmem, hbm_memdc)
ReleaseDC(hdc); // this no longer needed
// now start rendering into hdcmem...
You'll want to keep the old bitmap handle selected out to put it back before destroying your custom one on shutdown. How you manage that is entirely up to you.