For the following: This is my main question:
*Most of all* should I be doing this making these combined (make multiple regions at the same time) or in separate threads (if I am to have many of them)?
I asked about some bitmap regions in a previous post.
https://bytes.com/topic/c/answers/973517-c-11-seperately-controlled-regions
I do not know if I should have replaced the previous one or added to it.
In a later discussion I was reminded of multi-threading. I am now wondering if in my attempts to display two independent bitmap regions maybe together was incorrect. Maybe I should have considered multi-threading them separately.
(1)
Make a bitmap region, save it somehow, then after that is completed make a second bitmap and save it. Then copy those to the screen (dc?).
or
(2)
This is stretching my capacity as I started in C++ ~6 months ago: Create two threads: Create a thread and make one bitmap custom region in a thread and save it to a global (dc?); Create a second thread and make a second bitmap custom region in that thread and save it to a second global (dc?). Then, when both threads report completed, combine the bitmap custom regions into one single region and put it to the screen (dc?).
That was intense to just write in.
Thoughts?
I kind of have this written. Not fully, but here it is.
NOTE: Problem: It kind of works, but it first shows a square grey window which I do not want but which goes away (I do not want it at all), then it shows a red X then it shows a blue mess, then the red X turns grey.
The now-grey X when I leftmouse click on it becomes forefront and can be moved. The blue mess when I left mouse click on it becomes forefront and can be moved.
Please help me to make the red X stay red.
Please help me to make the initial grey square not show up.
Please help me to make certain that I am cleaning up any memory correctly.
But *most of all* should I be doing this making these combined or in separate threads (if I am to have many of them)?
Thanks.
(I am including it all since I have read multiple times where readers have asked for more information from the poster.)
main.cpp
------------------------------
resource.h
------------------------------
resource.rc
------------------------------
manifest.xml
(Put in your own codeblocks public key token at the xxxxxxxxxx area.
------------------------------
Here is what I get:
[ATTACH]a.bmp[/ATTACH]
[ATTACH]b.bmp[/ATTACH]
[ATTACH]c.bmp[/ATTACH]
[ATTACH]d.bmp[/ATTACH]
[ATTACH]e.bmp[/ATTACH]
The attach stuff does not seem to work in the preview mode. I hope it shows up in on the page.
*Most of all* should I be doing this making these combined (make multiple regions at the same time) or in separate threads (if I am to have many of them)?
I asked about some bitmap regions in a previous post.
https://bytes.com/topic/c/answers/973517-c-11-seperately-controlled-regions
I do not know if I should have replaced the previous one or added to it.
In a later discussion I was reminded of multi-threading. I am now wondering if in my attempts to display two independent bitmap regions maybe together was incorrect. Maybe I should have considered multi-threading them separately.
(1)
Make a bitmap region, save it somehow, then after that is completed make a second bitmap and save it. Then copy those to the screen (dc?).
or
(2)
This is stretching my capacity as I started in C++ ~6 months ago: Create two threads: Create a thread and make one bitmap custom region in a thread and save it to a global (dc?); Create a second thread and make a second bitmap custom region in that thread and save it to a second global (dc?). Then, when both threads report completed, combine the bitmap custom regions into one single region and put it to the screen (dc?).
That was intense to just write in.
Thoughts?
I kind of have this written. Not fully, but here it is.
NOTE: Problem: It kind of works, but it first shows a square grey window which I do not want but which goes away (I do not want it at all), then it shows a red X then it shows a blue mess, then the red X turns grey.
The now-grey X when I leftmouse click on it becomes forefront and can be moved. The blue mess when I left mouse click on it becomes forefront and can be moved.
Please help me to make the red X stay red.
Please help me to make the initial grey square not show up.
Please help me to make certain that I am cleaning up any memory correctly.
But *most of all* should I be doing this making these combined or in separate threads (if I am to have many of them)?
Thanks.
(I am including it all since I have read multiple times where readers have asked for more information from the poster.)
main.cpp
Code:
#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif
#ifndef _UNICODE
#define _UNICODE
#endif // _UNICODE
#ifndef UNICODE
#define UNICODE
#endif // UNICODE
//#include "JM_Defines_and_Includes.h"
//----------
#include "windows.h"
#include "resource.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE InstanceHandleOfMainWindow; // Instance handle of the main window
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
HWND Handle_MainWindow = NULL; // Handle to main application window
HRGN hRgn = NULL; // Handle to region
HDC hdcDest; // Dest DC
HDC hdcMem; // Memory DC
BITMAP bmpInfo; // Buffer to hold bitmap data
BOOL mouseState = 0; // Global variable for moving region using mouse
POINT CursPt = {0}; // Global variable for moving region using mouse
wchar_t WindowClass_for_WinMain[MAX_LOADSTRING] = L"(myWindowClass)";
// const wchar_t WindowClass_for_WinMain[MAX_LOADSTRING] = L"(myWindowClass)";
// Forward declarations of functions included later in this code module:
ATOM RegisterTheMainWindowClass(HINSTANCE hInstance2);
BOOL DidTheMainWindowClassRegisterCorrectly(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
// Empty function to be used later to create region based on the bitmap
void createRegion_A(HWND);
void createRegion_B(HWND);
// Empty Function to be used later to paint a region window
void paintRegion();
// Empty Dialog callback procedure declaration to be used later
INT_PTR CALLBACK DialogProc( HWND Handle_DialogBox1, UINT uMsg, WPARAM wParam, LPARAM lParam );
int APIENTRY WinMain(HINSTANCE hInstance1, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
RegisterTheMainWindowClass(hInstance1);
if (!DidTheMainWindowClassRegisterCorrectly (hInstance1, nCmdShow))
{
return FALSE;
}
// Message loop
while (GetMessage(&msg, nullptr, 0, 0))
{
DispatchMessage(&msg);
}
return msg.wParam;
}
ATOM RegisterTheMainWindowClass(HINSTANCE hInstance3)
// An ATOM is created when the class is registered.
// This might be a secure reference to window class in that it is special to the kernel.
// Maybe (typedef unsigned short ATOM;)
// ATOM is a 16-bit Windows handle-like primitive.
// It is value is completely opaque to user-mode.
// It is not a pointer or an index.
// They are indexes into a handle table in kernel mode.
// They are deliberately opaque because leaking kernel mode
// pointers to user-mode is a security violation (whatever that means).
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
// CS_HREDRAW is for HORIZONTAL;
// It redraws the entire window if a movement or size adjustment changes the width of the client area.
// CS_VREDRAW is for VERTICAL;
// It redraws the entire window if a movement or size adjustment changes the height of the client area.
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance3;
wcex.hIcon = nullptr;
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = WindowClass_for_WinMain;
wcex.hIconSm = nullptr;
// Return type is ATOM.
return RegisterClassEx(&wcex);
}
BOOL DidTheMainWindowClassRegisterCorrectly(HINSTANCE hInstance4, int nCmdShow)
{
InstanceHandleOfMainWindow = hInstance4; // Store the instance handle in a previously created global variable
Handle_MainWindow = CreateWindow(
WindowClass_for_WinMain,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
100,
150,
NULL,
NULL,
hInstance4,
NULL);
if (!Handle_MainWindow)
{
return FALSE;
}
// Create a dialog box
HWND Handle_DialogBox2 = CreateDialog(hInstance4, MAKEINTRESOURCE(IDD_DIALOG1), Handle_MainWindow, (DLGPROC)DialogProc);
// Create a region
createRegion_A(Handle_DialogBox2);
HWND Handle_DialogBox3 = CreateDialog(hInstance4, MAKEINTRESOURCE(IDD_DIALOG1), Handle_MainWindow, (DLGPROC)DialogProc);
// Create a region
createRegion_B(Handle_DialogBox3);
// Don't have to show or update the window ?
// ShowWindow(hWnd, nCmdShow);
// UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
{
DeleteObject(hRgn);
DeleteDC(hdcMem); //Delete the memory DC
DeleteDC(hdcDest); //delete the dest DC
PostQuitMessage(0);
}
return TRUE;
break;
default:
{
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
INT_PTR CALLBACK DialogProc( // Dialog callback procedure
// INT_PTR is a signed integer memsize-type
// that can store a pointer regardless of the platform capacity.
HWND Handle_DialogBox01, // Temporary (internal to this procedure) Handle to a dialog box
UINT uMsg, // Message
WPARAM wParam, // First message parameter
LPARAM lParam // Second message parameter
)
{
switch (uMsg)
{
case WM_PAINT:
{
paintRegion();
ValidateRect(Handle_DialogBox01,nullptr); // ValidateRect(hwnd,FALSE);
}
return TRUE;
break;
case WM_MOVE:
{
//does not work here.
//RedrawWindow(Handle_MainWindow, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
paintRegion();
}
return TRUE;
break;
case WM_LBUTTONDOWN:
{
mouseState = 1;
/*BOOL RedrawWindow(
HWND hWnd,
const RECT *lprcUpdate,
HRGN hrgnUpdate,
UINT flags
);
*/
//Almost works here but back image is partially greyed out.
RedrawWindow(Handle_MainWindow, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
}
return TRUE;
break;
case WM_MOUSEMOVE:
{
if(mouseState)
{
GetCursorPos(&CursPt);
PostMessage(Handle_DialogBox01, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( CursPt.x, CursPt.y));
mouseState = 0;
}
}
return TRUE;
break;
case WM_RBUTTONDOWN:
{
// Destroy the dialog box
EndDialog(Handle_DialogBox01,0);
// Send message to destroy the main application window and exit
SendMessage(Handle_MainWindow,WM_DESTROY,0,0);
}
return TRUE;
break;
default :
{
break;
}
return TRUE;
break;
}
return FALSE;
}
void createRegion_A(HWND FunctionReferenceTo_DialogBox01)
{
HGDIOBJ hGdiObj; // For Selecting a bitmap into the dc
COLORREF crTransparent;
int iX = 0;
int iY = 0;
int iRet01 = 0; // Integer For region 1
// Get the destination device context
hdcDest = GetDC(FunctionReferenceTo_DialogBox01);
// Create a memory DC
hdcMem = CreateCompatibleDC(nullptr);
HRGN FinalTransparentRegionFrom_Combined_Bitmaps;
FinalTransparentRegionFrom_Combined_Bitmaps = CreateRectRgn(0,0,0,0);
//----------------------------------------------------------------------
// START Load the image files
//----------------------------------------------------------------------
// a.bmp
wchar_t imageFile_A[] = L"a.bmp";
// Load the image
HANDLE Handle_Bitmap_A = (HBITMAP)LoadImage(GetModuleHandle(nullptr), imageFile_A, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if(!Handle_Bitmap_A)
{
// Handle error here
return;
}
//----------------------------------------------------------------------
// END Load the image files
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// START Create Region from imageFile_A
//----------------------------------------------------------------------
HRGN TemporaryRegion_for_Bitmap_A;
HRGN FinalTransparentRegionFromBitmap_A;
// Get information about the bitmap..
GetObject(Handle_Bitmap_A, sizeof(bmpInfo), &bmpInfo); // Get info about the bitmap
// Select the bitmap into the dc
hGdiObj = SelectObject(hdcMem, Handle_Bitmap_A);
// Create a region from a bitmap with transparency colour of white
// change the pixel values for a different transparency color
// example - RGB(0,0,0) will mean a transparency color of black.. so the areas
// of the bitmap not used to create the window will be black
// COLORREF crTransparent = RGB(255, 255, 255);
crTransparent = RGB(255, 255, 255);
iX = 0;
iY = 0;
iRet01 = 0;
FinalTransparentRegionFromBitmap_A = CreateRectRgn(0,0,0,0);
for (iY = 0; iY < bmpInfo.bmHeight; iY++)
{
do
{
// Skip over transparent pixels at start of lines.
while (iX < bmpInfo.bmWidth && GetPixel(hdcMem, iX, iY) == crTransparent)
{
iX++;
}
// Remember this pixel
int iLeftX = iX;
// Now find first non transparent pixel
while (iX < bmpInfo.bmWidth && GetPixel(hdcMem, iX, iY) != crTransparent)
{
++iX;
}
// Create a temp region on this info
TemporaryRegion_for_Bitmap_A = CreateRectRgn(iLeftX, iY, iX, iY+1);
// Combine into main region.
// From wingdi.h
// WINGDIAPI int WINAPI CombineRgn(HRGN,HRGN,HRGN,int);
// Combine Region1 & Region2 & store result in ResultRegion.
// CombineRgn(ResultRegion,Region1,Region2,RGN_AND);
iRet01 = CombineRgn(FinalTransparentRegionFromBitmap_A, FinalTransparentRegionFromBitmap_A, TemporaryRegion_for_Bitmap_A, RGN_OR);
}
while(iX < bmpInfo.bmWidth);
{
iX = 0;
}
}
// Center it on current desktop
iRet01 = SetWindowRgn(FunctionReferenceTo_DialogBox01, FinalTransparentRegionFromBitmap_A, TRUE);
if(!iRet01)
{
return;
}
iX = (GetSystemMetrics(SM_CXSCREEN)) / 3 - (bmpInfo.bmWidth / 3);
iY = (GetSystemMetrics(SM_CYSCREEN)) / 3 - (bmpInfo.bmHeight / 3);
iRet01 = SetWindowPos(FunctionReferenceTo_DialogBox01, HWND_TOPMOST, iX, iY, bmpInfo.bmWidth, bmpInfo.bmHeight, 0);
//----------------------------------------------------------------------
// END Create Region from imageFile_A
//----------------------------------------------------------------------
// Copy the memory dc into the screen dc
paintRegion();
// Delete the bitmap
DeleteObject(Handle_Bitmap_A);
} //void createRegion_A(HWND FunctionReferenceTo_DialogBox01)
void createRegion_B(HWND FunctionReferenceTo_DialogBox01)
{
HGDIOBJ hGdiObj; // For Selecting a bitmap into the dc
COLORREF crTransparent;
int iX = 0;
int iY = 0;
int iRet01 = 0; // Integer For region 1
int iRet02 = 0; // Integer For region 2
int iRet03 = 0; // Integer For combined (already) transparent regions
// Get the destination device context
hdcDest = GetDC(FunctionReferenceTo_DialogBox01);
// Create a memory DC
hdcMem = CreateCompatibleDC(nullptr);
HRGN FinalTransparentRegionFrom_Combined_Bitmaps;
FinalTransparentRegionFrom_Combined_Bitmaps = CreateRectRgn(0,0,0,0);
//----------------------------------------------------------------------
// START Load the image files
//----------------------------------------------------------------------
// b.bmp
wchar_t imageFile_B[] = L"b.bmp";
// Load the image
HANDLE Handle_Bitmap_B = (HBITMAP)LoadImage(GetModuleHandle(nullptr), imageFile_B, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if(!Handle_Bitmap_B)
{
// Handle error here
return;
}
//----------------------------------------------------------------------
// END Load the image files
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// START Create Region from imageFile_B
//----------------------------------------------------------------------
HRGN TemporaryRegion_for_Bitmap_B;
HRGN FinalTransparentRegionFromBitmap_B;
// Get information about the bitmap..
GetObject(Handle_Bitmap_B, sizeof(bmpInfo), &bmpInfo); // Get info about the bitmap
// Select the bitmap into the dc
hGdiObj = SelectObject(hdcMem, Handle_Bitmap_B);
// Create a region from a bitmap with transparency colour of white
// change the pixel values for a different transparency color
// example - RGB(0,0,0) will mean a transparency color of black.. so the areas
// of the bitmap not used to create the window will be black
// COLORREF crTransparent = RGB(255, 255, 255);
crTransparent = RGB(255, 255, 255);
iX = 0;
iY = 0;
iRet02 = 0; // For region 2
FinalTransparentRegionFromBitmap_B = CreateRectRgn(0,0,0,0);
for (iY = 0; iY < bmpInfo.bmHeight; iY++)
{
do
{
// Skip over transparent pixels at start of lines.
while (iX < bmpInfo.bmWidth && GetPixel(hdcMem, iX, iY) == crTransparent)
iX++;
// Remember this pixel
int iLeftX = iX;
// Now find first non transparent pixel
while (iX < bmpInfo.bmWidth && GetPixel(hdcMem, iX, iY) != crTransparent)
++iX;
// Create a temp region on this info
TemporaryRegion_for_Bitmap_B = CreateRectRgn(iLeftX, iY, iX, iY+1);
// Combine into main region.
// From wingdi.h
// WINGDIAPI int WINAPI CombineRgn(HRGN,HRGN,HRGN,int);
// Combine Region1 & Region2 & store result in ResultRegion.
// CombineRgn(ResultRegion,Region1,Region2,RGN_AND);
iRet02 = CombineRgn(FinalTransparentRegionFromBitmap_B, FinalTransparentRegionFromBitmap_B, TemporaryRegion_for_Bitmap_B, RGN_OR);
}
while(iX < bmpInfo.bmWidth);
{
iX = 0;
}
}
// Center it on current desktop
iRet02 = SetWindowRgn(FunctionReferenceTo_DialogBox01, FinalTransparentRegionFromBitmap_B, TRUE);
if(!iRet02)
{
return;
}
iX = (GetSystemMetrics(SM_CXSCREEN)) / 3 - (bmpInfo.bmWidth / 3);
iY = (GetSystemMetrics(SM_CYSCREEN)) / 3 - (bmpInfo.bmHeight / 3);
iRet02 = SetWindowPos(FunctionReferenceTo_DialogBox01, HWND_TOPMOST, iX, iY, bmpInfo.bmWidth, bmpInfo.bmHeight, 0);
//----------------------------------------------------------------------
// END Create Region from imageFile_B
//----------------------------------------------------------------------
// Copy the memory dc into the screen dc
paintRegion();
// Delete the bitmap
DeleteObject(Handle_Bitmap_B);
} //void createRegion_B(HWND FunctionReferenceTo_DialogBox01)
void paintRegion()
{
// Transfer color data from the source device context to the destination device context
BitBlt(hdcDest, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, hdcMem, 0, 0, SRCCOPY);
UpdateWindow(Handle_MainWindow);
RedrawWindow(Handle_MainWindow, nullptr, nullptr, RDW_UPDATENOW);
}
resource.h
Code:
#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif
#ifndef _UNICODE
#define _UNICODE
#endif // _UNICODE
#ifndef UNICODE
#define UNICODE
#endif // UNICODE
#define IDD_DIALOG1 101
resource.rc
Code:
#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif
#ifndef _UNICODE
#define _UNICODE
#endif // _UNICODE
#ifndef UNICODE
#define UNICODE
#endif // UNICODE
#include <windows.h>
#include <commctrl.h>
//#include <richedit.h>
#include "resource.h"
LANGUAGE 0, SUBLANG_NEUTRAL
1 RT_MANIFEST ".\\manifest.xml"
//----------
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95
STYLE DS_SYSMODAL | WS_POPUP | WS_VISIBLE
//CAPTION "Hello" //Any setting of this Dialog's Caption (including blank "") seems to makes this dialog not be shaped correctly.
{
}
manifest.xml
(Put in your own codeblocks public key token at the xxxxxxxxxx area.
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="xxxxxxxxxx" language="*"/> </dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
------------------------------
Here is what I get:
[ATTACH]a.bmp[/ATTACH]
[ATTACH]b.bmp[/ATTACH]
[ATTACH]c.bmp[/ATTACH]
[ATTACH]d.bmp[/ATTACH]
[ATTACH]e.bmp[/ATTACH]
The attach stuff does not seem to work in the preview mode. I hope it shows up in on the page.
Comment