c++ GDI printing causes system to freeze - c++

I am curently maintaining an old peace of c++ sofware that creates labels for SD-Cards. The software uses GDI to create the print jobs and usually there is no problem with that. However, after a certain amount of prints, the system freezes forever, even the mouse does not respond anymore. I can't tell where the app crashes, because it happens at different points and it is totally unpredictabe. I am not even sure what code I need to show here.
I aready set loads of breakpoints and stepped through different parts of the code but as the problem appears only randomly, it was not possible for me to come to any conclusion. I also tried to run the app on different environments, such as a VM but regardless what machine I use, the problem reappears.
HDC printerDC = CreateDCW(L"WINSPOOL", printers[SELECTED_PRINTERS[printerIndex]].c_str(), NULL, NULL);
DODEBUG(L"CreateDCW returned: " << printerDC << L" (should be something else than 0), GetLastError: " << GetLastError() << L" (should be 0)", L"CreateDCW");
SetGraphicsMode(printerDC, GM_ADVANCED);
int result4 = StartDocW(printerDC, &di);
DODEBUG(L"StartDocW returned: " << result4 << L" (should be greater than 0), GetLastError: " << GetLastError() << L" (should be 0)", L"StartDocW");
if(result4 > 0)
{
int result5 = StartPage(printerDC);
DODEBUG(L"StartPage returned: " << result5 << L" (should be greater than 0), GetLastError: " << GetLastError() << L" (should be 0)", L"StartPage");
SetBkMode(printerDC, TRANSPARENT);
//1 dpi = 0.03937 pixel/mm; 1 pixel/mm = 25.4 dpi; 1 dpi = 0.003937 pixel/papersize; 0.1 pixel/papersize = 25.4 dpi;
//1 px / 1 mm = 25.4 dpi => 1 px = 25.4 dpi * 1 mm => 1/(25.4) px = 25.4 dpi * 1 mm
//1 dpi = 0.03937 pixel/mm => 1dpi * 1mm = 0.03937 pixel
BITMAPINFOHEADER bi = { 0 };
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biHeight = (printerPaperYResolution * printLength) / 254;
bi.biWidth = (printerPaperXResolution * printWidth) / 254;
bi.biPlanes = 1;
bi.biBitCount = 24;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
//Fix divisible-by-4-bug:
LONG byteWidth = bi.biWidth * 3;
LONG xDiv = byteWidth % 12;
if(xDiv > 0)
{
bi.biWidth += (12 - xDiv) / 3;
byteWidth = bi.biWidth * 3;
}
LONG yDiv = (bi.biHeight * 3) % 12;
if(yDiv > 0)
{
bi.biHeight += (12 - yDiv) / 3;
}
LONG byteCount = 3 * bi.biHeight*bi.biWidth;
byte* pBits = new byte[byteCount];
memset(pBits, 255, byteCount);
switch(printerIndex)
{
case PRINTER_ZERTIFIKAT:
PrintZertifikat(sdCardData, printerDC, pBits, byteCount, byteWidth, &bi);
break;
case PRINTER_LABEL_PACKUNG:
PrintLabelPackung(sdCardData, printerDC, pBits, byteCount, byteWidth, &bi);
break;
case PRINTER_LABEL_SDKARTE:
PrintLabelSDKarte(sdCardData, printerDC, pBits, byteCount, byteWidth, &bi);
break;
case PRINT_ONLY_SDLABEL:
PrintOnlySDLabel(sdCardData, printerDC, pBits, byteCount, byteWidth, &bi);
break;
}
int result6 = EndPage(printerDC);
DODEBUG(L"EndPage returned: " << result6 << L" (should be greater than 0), GetLastError: " << GetLastError() << L" (should be 0)", L"EndPage");
int result7 = EndDoc(printerDC);
}

Do you release your HDC properly with DeleteDC()?

Related

Troubles capturing screen with winapi

I've been trying to capture the screen of my display using c++ and winapi to later convert it to a DIB for modifications. So far I've came up with this, in accordance with every guide out there:
#include "targetver.h"
#include "windows.h"
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <chrono>
void mainloop()
{
auto start = std::chrono::steady_clock::now();
HDC hdcScreen = GetDC(NULL);
if (!hdcScreen)
{
std::cout << "Couldn't get DC for screen\n";
}
auto width = GetSystemMetrics(SM_CXSCREEN);
auto height = GetSystemMetrics(SM_CYSCREEN);
HDC memDc = CreateCompatibleDC(hdcScreen);
if (!memDc)
{
std::cout << "Create compatible DC failed!\n";
}
HBITMAP hScreenBmp = CreateCompatibleBitmap(memDc, width, height);
BITMAP bmpScreen;
if (!hScreenBmp)
{
std::cout << "CreateCompatibleBitmap to screen failed\n";
}
SelectObject(memDc, hScreenBmp);
if (!BitBlt(memDc,
0, 0,
width, height,
hdcScreen,
0, 0,
SRCCOPY))
{
std::cout << "BitBlt failed\n";
}
GetObject(hScreenBmp, sizeof(BITMAP), &bmpScreen);
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmpScreen.bmWidth;
bi.biHeight = bmpScreen.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
char* lpbitmap = (char*)GlobalLock(hDIB);
GetDIBits(memDc, hScreenBmp, 0,
(UINT)bmpScreen.bmHeight,
lpbitmap,
(BITMAPINFO*)&bi, DIB_RGB_COLORS);
std::cout << "Lines: " << bi.biWidth << " x " << bi.biHeight << "px \n";
char* currPixel = (char*)lpbitmap;
for (auto j = 0; j < bi.biHeight; j++)
{
std::cout << "Line" << j << ":\n";
for (auto i = 0; i < bi.biWidth; i++)
{
std::cout << "(" << std::to_string(static_cast<unsigned char>(currPixel[0])) << "," << std::to_string(static_cast<unsigned char>(currPixel[1]))
<< "," << std::to_string(static_cast<unsigned char>(currPixel[2])) << ")\t";
currPixel += 4;
}
std::cout << std::endl;
}
GlobalUnlock(hDIB);
GlobalFree(hDIB);
DeleteDC(hdcScreen);
DeleteDC(memDc);
auto end = std::chrono::steady_clock::now();
std::cout << "Main loop completed in: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms\n";
}
int main()
{
mainloop();
}
(and also every other variation of the above I could think of). However, the loop at the ends tries to print the values of the pixels in the DIB - and, unfortunately, all come out zeros: "(0,0,0)...". Not sure what the problem may be here and I'd love some feedback that could shed some light on this. I should probably note that the screen has a resolution of 3820x2160 pixels so the memory allocation needed for the bitmap is rather large. Also, this is a terminal-type program and not a windows-one (maybe something is not properly configured/linked - dunno - just guessing). I also tried moving the BitBlt call to every possible spot but to no avail (not sure at which time it should be called for the desired effect). Thanks for the help!

openvino FormatReader vs cv::Mat image = cv::imdecode

i am trying to convert openvino c++ object_detection_ssd sample to dll library, so that i can use it in my c# application.
below is my code c++ code to export function
__declspec(dllexport) void Classify_Image(unsigned char* img_pointer, long data_len,
char* out_result, int length_of_out_result, int top_n_results)
{
std::vector<unsigned char> inputImageBytes(img_pointer, img_pointer + data_len);
cv::Mat image = cv::imdecode(inputImageBytes,cv::IMREAD_COLOR);
//cv::imwrite("lala.jpg", image);
if (inputInfo == nullptr) {
initialize();
}
// --------------------------- 8. Create infer request -------------------------------------------------
//slog::info << "Create infer request" << slog::endl;
InferRequest infer_request = executable_network.CreateInferRequest();
// -----------------------------------------------------------------------------------------------------
std::vector<std::shared_ptr<unsigned char>> imagesData, originalImagesData;
std::vector<size_t> imageWidths, imageHeights;
//FormatReader::ReaderPtr reader("C:\\Users\\Sam\\Desktop\\la.jpg");
cv::Mat dst;
cv::resize(image, dst, cv::Size(400, 225));
cv::imwrite("lala_m.jpg", dst);
//std::shared_ptr<unsigned char> originalData(image.data);
std::shared_ptr<unsigned char> originalData(image.data);
std::shared_ptr<unsigned char> data1(dst.data);
//
originalImagesData.push_back(originalData);
imagesData.push_back(data1);
imageWidths.push_back(1280);
imageHeights.push_back(720);
if (imagesData.empty()) throw std::logic_error("Valid input images were not found!");
size_t batchSize = network.getBatchSize();
if (batchSize != imagesData.size()) {
slog::warn << "Number of images " + std::to_string(imagesData.size()) + \
" doesn't match batch size " + std::to_string(batchSize) << slog::endl;
batchSize = std::min(batchSize, imagesData.size());
slog::warn << "Number of images to be processed is " << std::to_string(batchSize) << slog::endl;
}
///** Creating input blob **/
Blob::Ptr imageInput = infer_request.GetBlob(imageInputName);
///** Filling input tensor with images. First b channel, then g and r channels **/
MemoryBlob::Ptr mimage = as<MemoryBlob>(imageInput);
if (!mimage) {
slog::err << "We expect image blob to be inherited from MemoryBlob, but by fact we were not able "
"to cast imageInput to MemoryBlob" << slog::endl;
return;
}
//// locked memory holder should be alive all time while access to its buffer happens
auto minputHolder = mimage->wmap();
size_t num_channels = mimage->getTensorDesc().getDims()[1];
size_t image_size = mimage->getTensorDesc().getDims()[3] * mimage->getTensorDesc().getDims()[2];
unsigned char *data = minputHolder.as<unsigned char *>();
/** Iterate over all input images **/
for (size_t image_id = 0; image_id < std::min(imagesData.size(), batchSize); ++image_id) {
/** Iterate over all pixel in image (b,g,r) **/
for (size_t pid = 0; pid < image_size; pid++) {
/** Iterate over all channels **/
for (size_t ch = 0; ch < num_channels; ++ch) {
/** [images stride + channels stride + pixel id ] all in bytes **/
data[image_id * image_size * num_channels + ch * image_size + pid] = imagesData.at(image_id).get()[pid*num_channels + ch];
}
}
}
if (imInfoInputName != "") {
Blob::Ptr input2 = infer_request.GetBlob(imInfoInputName);
auto imInfoDim = inputsInfo.find(imInfoInputName)->second->getTensorDesc().getDims()[1];
/** Fill input tensor with values **/
MemoryBlob::Ptr minput2 = as<MemoryBlob>(input2);
if (!minput2) {
slog::err << "We expect input2 blob to be inherited from MemoryBlob, but by fact we were not able "
"to cast input2 to MemoryBlob" << slog::endl;
return;
}
// locked memory holder should be alive all time while access to its buffer happens
auto minput2Holder = minput2->wmap();
float *p = minput2Holder.as<PrecisionTrait<Precision::FP32>::value_type *>();
for (size_t image_id = 0; image_id < std::min(imagesData.size(), batchSize); ++image_id) {
p[image_id * imInfoDim + 0] = static_cast<float>(inputsInfo[imageInputName]->getTensorDesc().getDims()[2]);
p[image_id * imInfoDim + 1] = static_cast<float>(inputsInfo[imageInputName]->getTensorDesc().getDims()[3]);
for (size_t k = 2; k < imInfoDim; k++) {
p[image_id * imInfoDim + k] = 1.0f; // all scale factors are set to 1.0
}
}
}
// -----------------------------------------------------------------------------------------------------
// --------------------------- 10. Do inference ---------------------------------------------------------
slog::info << "Start inference" << slog::endl;
infer_request.Infer();
// -----------------------------------------------------------------------------------------------------
// --------------------------- 11. Process output -------------------------------------------------------
slog::info << "Processing output blobs" << slog::endl;
const Blob::Ptr output_blob = infer_request.GetBlob(outputName);
MemoryBlob::CPtr moutput = as<MemoryBlob>(output_blob);
if (!moutput) {
throw std::logic_error("We expect output to be inherited from MemoryBlob, "
"but by fact we were not able to cast output to MemoryBlob");
}
// locked memory holder should be alive all time while access to its buffer happens
auto moutputHolder = moutput->rmap();
const float *detection = moutputHolder.as<const PrecisionTrait<Precision::FP32>::value_type *>();
std::vector<std::vector<int> > boxes(batchSize);
std::vector<std::vector<int> > classes(batchSize);
///* Each detection has image_id that denotes processed image */
std::string result = "OB_DATA=";
int num_detect = 0;
for (int curProposal = 0; curProposal < maxProposalCount; curProposal++) {
auto image_id = static_cast<int>(detection[curProposal * objectSize + 0]);
if (image_id < 0 ) {
slog::info << "ends with break "<<slog::endl;
break;
}
float confidence = detection[curProposal * objectSize + 2];
auto label = static_cast<int>(detection[curProposal * objectSize + 1]);
auto xmin = static_cast<int>(detection[curProposal * objectSize + 3] * imageWidths[image_id]);
auto ymin = static_cast<int>(detection[curProposal * objectSize + 4] * imageHeights[image_id]);
auto xmax = static_cast<int>(detection[curProposal * objectSize + 5] * imageWidths[image_id]);
auto ymax = static_cast<int>(detection[curProposal * objectSize + 6] * imageHeights[image_id]);
std::cout << "[" << curProposal << "," << label << "] element, prob = " << confidence <<
" (" << xmin << "," << ymin << ")-(" << xmax << "," << ymax << ")" << " batch id : " << image_id;
if (confidence > 0.5) {
num_detect += 1;
result += std::to_string(confidence);
result += ","+ std::to_string(label);
result += "," + std::to_string(xmin);
result += "," + std::to_string(ymin);
result += "," + std::to_string(xmax);
result += "," + std::to_string(ymax);
/** Drawing only objects with >50% probability **/
classes[image_id].push_back(label);
boxes[image_id].push_back(xmin);
boxes[image_id].push_back(ymin);
boxes[image_id].push_back(xmax - xmin);
boxes[image_id].push_back(ymax - ymin);
//std::cout << " WILL BE PRINTED!";
/*std::cout << std::endl;*/
//slog::info << " add prediction" << slog::endl;
}
result += ";";
std::cout << std::endl;
}
data1.reset();
originalData.reset();
//dst.release();
//image.release();
length_of_out_result = (int)result.size();
std::copy(result.begin(), result.end(), out_result);
out_result[std::min(length_of_out_result - 1, (int)result.size())] = 0;
std::cout << "end code"<<std::endl;
}
}
in the code above i am trying to decode my byte array which i send from c# to opencv mat and run inference on mat object, so when i call this function from c# it works fine but after printing "end code" line it gives error in my c# application, below is my code in c#, my c# application can't print Console.WriteLine("after call"); and in the visual studio output i can see last line printed by c++ function which is "end code"
[DllImport("object_detection_sample_ssd.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void Classify_Image(byte[] img, long data_len, StringBuilder out_result, int out_result_length, int top_n_results = 2);
private void button3_Click(object sender, EventArgs e)
{
byte[] result = new byte[200];
Image img = Image.FromFile(#"C:\Users\Sam\Desktop\la.jpg");
ImageFormat fmt = new ImageFormat(img.RawFormat.Guid);
var imageCodecInfo = ImageCodecInfo.GetImageEncoders().FirstOrDefault(codec => codec.FormatID == img.RawFormat.Guid);
//this is for situations, where the image is not read from disk, and is stored in the memort(e.g. image comes from a camera or snapshot)
if (imageCodecInfo == null)
{
fmt = ImageFormat.Jpeg;
}
//Image img = Image.FromFile(#"");
using (MemoryStream ms = new MemoryStream())
{
img.Save(ms, fmt);
byte[] image_byte_array = ms.ToArray();
int len_result=300;
int STRING_MAX_LENGTH1 = 300;
StringBuilder str1 = new StringBuilder(STRING_MAX_LENGTH1);
Classify_Image(image_byte_array, ms.Length, str1, len_result, 2);
Console.WriteLine("after call");
}
Console.WriteLine("even after using");
Console.WriteLine("output ="+ ASCIIEncoding.ASCII.GetString(result));
}
i dont know what is wrong with that, in the original example of openvino toolkit there is a FormatReader.h file which is used to load image from image file path, i have tried with passing image file name and use FormatReader as original and it works. FormatReader https://github.com/openvinotoolkit/openvino/tree/master/inference-engine/samples/common/format_reader
please help!
I suggest you refer to Hello Classification C++ Sample, which loads image from Mat for inferencing. The main.cpp file is available at the following link:
https://github.com/openvinotoolkit/openvino/blob/master/inference-engine/samples/hello_classification/main.cpp

Receiving char array via MPI_Recv results in the output image being partially black

I am calculating a picture and i am using OpenMPI to destribute my loop onto several cores.
Every core calculates a part of the loop correctly, but merging
both arrays on the core with rank 0 results in part of the picture being black.
I do not know if sending/receiving the char array corrupts the data or
if my merge is not correct.
(My virtual machine has 2 cores).
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <xmmintrin.h>
#include "complex.h"
#include "lodepng.h"
using namespace std;
#include <sys/time.h>
#include <mpi.h>
int julia(int width, int height, int x, int y, const complex &c, const int max_iter) {
/*
* calculates the number of iterations (between 0 and 255) for a pixel (x,y)
*/
complex z(1.5f * (x - width / 2) / (0.5f * width), (y - height / 2) / (0.5f * height));
int n = 0;
for (int i = 0; ((z.abs() < 2.0f) && (i < max_iter)); i++) {
float tmp = z.re() * z.re() - z.im() * z.im() + c.re();
z.set_im(2.0f * z.re() * z.im() + c.im());
z.set_re(tmp);
n++;
}
return max_iter - n;
}
int main(int argc, char **argv) {
int rank, num_procs;
//Initialize the infrastructure necessary for coomunication
MPI_Init(&argc, &argv);
//Identify this process
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
//Find out how many processes are active
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
const complex c(-0.7, 0.27015); // pretty
// const complex c( -0.8, 0.156); // alternative complex number
const int width = 2 * 1024, height = 2 * 1024; // image size
int max_iter = 256;
// Allocate aligned image buffer
unsigned char *image = NULL;
int err = posix_memalign((void **) &image, 64, width * height * 4 * sizeof(unsigned char));
if (err){
cout << "[Error] Couldn't allocate memory for regular Image." << endl;
}
int count = height / num_procs;
int remainder = height % num_procs;
int start, stop;
if (rank < remainder) {
// The first 'remainder' ranks get 'count + 1' tasks each
start = rank * (count + 1);
stop = start + count;
} else {
// The remaining 'size - remainder' ranks get 'count' task each
start = rank * count + remainder;
stop = start + (count - 1);
}
/*
* Creates a pictures of a julia set
*/
cout << "--------------------- " << endl;
cout << "my rank " << rank << endl;
cout << "number of procs " << num_procs << endl;
cout << "start " << start << endl;
cout << "end " << stop << endl;
cout << "--------------------- "<< endl;
// iterate over image pixels and calculate their value
for (int y = start; y <= stop; y++) {
for (int x = 0; x < width; x++) {
int a = julia(width, height, x, y, c, max_iter);
image[4 * width * y + 4 * (x + 0) + 0] = a; // R
image[4 * width * y + 4 * (x + 0) + 1] = a; // G
image[4 * width * y + 4 * (x + 0) + 2] = a; // B
image[4 * width * y + 4 * (x + 0) + 3] = 255; // Alpha
}
}
if(rank != 0)
{
//send image to rank 0
MPI_Send(image, sizeof(image), MPI_UNSIGNED_CHAR, 0, 0, MPI_COMM_WORLD);
}
if(rank == 0 && (num_procs > 0))
{
// Allocate aligned image buffer
unsigned char *lImage = (unsigned char *) malloc(width * height * 4 * sizeof(unsigned char));
/*
unsigned char *lImage = NULL;
int err = posix_memalign((void **) &lImage, 64, width * height * 4 * sizeof(unsigned char));
if (err){
cout << "[Error] Couldn't allocate memory for regular Image." << endl;
}
*/
for(int i = 1; i < num_procs; i++)
{
//lImage receives the image array from process i
MPI_Recv(lImage, sizeof(lImage), MPI_UNSIGNED_CHAR, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
//calculate start and stop for the following for loop
int lCount = height / num_procs;
int lRemainder = height % num_procs;
int lStart, lStop;
if (i < lRemainder) {
// The first 'remainder' ranks get 'count + 1' tasks each
lStart = i * (lCount + 1);
lStop = lStart + lCount;
} else {
// The remaining 'size - remainder' ranks get 'count' task each
lStart = i * lCount + lRemainder;
lStop = lStart + (lCount - 1);
}
cout << "--------inside loop----------- " << endl;
cout << "my rank " << i << endl;
cout << "start " << lStart << endl;
cout << "end " << lStop << endl;
cout << "--------------------- "<< endl;
for (int y = lStart; y <= lStop; y++) {
for (int x = 0; x < width; x++) {
image[4 * width * y + 4 * (x + 0) + 0] = lImage[4 * width * y + 4 * (x + 0) + 0]; // R
image[4 * width * y + 4 * (x + 0) + 1] = lImage[4 * width * y + 4 * (x + 0) + 1]; // G
image[4 * width * y + 4 * (x + 0) + 2] = lImage[4 * width * y + 4 * (x + 0) + 2]; // B
image[4 * width * y + 4 * (x + 0) + 3] = 255; // Alpha
}
}
//receive image of the rank i
//merge received image array and rank 0 image array
}
free(lImage);
}
if(rank == 0)
{
/*Encode the image*/
unsigned error = lodepng_encode32_file("julia_openmp0.png", image, width, height);
if (error) {
std::cout << "[Error] " << error << " : " << lodepng_error_text(error) << std::endl;
}
}
if(rank == 1)
{
/*Encode the image*/
unsigned error = lodepng_encode32_file("julia_openmp1.png", image, width, height);
if (error) {
std::cout << "[Error] " << error << " : " << lodepng_error_text(error) << std::endl;
}
}
/*cleanup*/
free(image);
/* Tear down the communication infrastructure */
MPI_Finalize();
return 0;
Sorry I had no chance to do a proper checking, but I think it boils down to this line:
MPI_Recv(lImage, sizeof(lImage), MPI_UNSIGNED_CHAR, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
You are trying to receive the messages in a particular order (process 1, process 2), while you don't really know which one is ready first. And MPI_Recv receive operation is blocking. Can you try to rewrite the logic in such a way that it does not depend on the order of computation? One way to do it would be to use MPI_Gather(). Another option would be to include process number into the message you send, then use MPI_ANY_SOURCE to receive the next incoming message and to use process number in the loop to handle the block correctly.

How can I give a window msg higher priority then other window msgs (so that a window msg can not interrupt it) (c++)

I'm not really sure how to word this question, so hopefully this makes sense...
I have a GUI working that reads value from a board, and displays them in a window. This window also has a menu. My problem is, when I click on a menu item, it seems to jump out of my Update function before it has completed, which gives me a communication error from my board (since the command was not completed before switching over to the menu processing). The problem is intermittent, since I do not always click the menu when the Update function is running.
Some additional info:
The Update function is sent periodically using the following
PostMessage(hwnd, WM_COMMAND, WM_USER+1, NULL);
case WM_USER+1:
{
debugFunc = 2;
Update();
InvalidateRect(hwnd, NULL, FALSE);
debugFunc = 2;
}
The debugFunc integer was used for debugging...whenever the window sent WM_ENTERMENULOOP or WM_EXITMENULOOP, I would break to see what this debugFunc value was...whenever I had a communication error, the debugFunc == 4 (debugFunc is set in Update function to 4)...meaning that this WM_USER+1 msg did not complete before the menu was called.
So, is there a way to give either the message WM_USER+1 or the function Update a higher priority then the menu call? So that WM_USER+1 or Update must be completed before the menu items are shown?
EDIT:: Here's update, it just sends a bunch of messages using an I2C adapter to get reads..
I didnt write any of the iPortAIMaster functions, they came with the adapter
void Update()
{
int receiveLength = 0;
debugFunc = 4;
//The following CStrings hold a string value that is to be updated to the window
CString newVoltage, newCurrent, newPower, newStatus;
CString StatusDisplay;
//The following act like flags
//If STATUS_WORD VOUT bit is set, checkVout = 1...meaning all pages must have their Vout Status checked
//The rest follow in a similar fashion
int checkTemp = 0, checkVout = 0, checkIout = 0, checkInput = 0;
//Holds the pBuf data output from a MasterTxRx command is sent
//Holds the new voltage or new current values
//Must be translated to a CString to update the window
BYTE *nV, *nC;
//Holds a bit position
int bit;
float valueV, valueC;
if (isOn)
{
pBufStatus[0] = 0x79; //STATUS_WORD
////buf += "\r\n Sending the STATUS_WORD command to check for errors";
//BYTE I2CAddr, BYTE *pBufStatus, unsigned int TxLen, unsigned int RxLen, BYTE doStop, UINT time
newPort.iPortAIMasterTxRx(I2CAddr, pBufStatus, 1, 2, 1, 820);
//Get the PAGE reading, value is placed in pBufStatus
receiveLength = newPort.iPortAIGetMasterRxMsg(512, pBufStatus);
//Store pBufStatus
pBufWORD[0] = pBufStatus[0];
pBufWORD[1] = pBufStatus[1];
#pragma region "Reading and Updating the window"
#pragma region "Reading new IN Volt Cur Pow"
{
valueV = 0;
valueC = 0;
//Read_VIN
pBufStatus[0] = 0x88; //Read_VIN Command
pBufStatus[1] = 0; //Clear out earlier command
//Send Read_VIN command
MasterTxRx(I2CAddr, pBufStatus, 1, 2, 1, 120);
//Get the Voltage Reading, value is placed in pBufStatus
newPort.iPortAIGetMasterRxMsg(512, pBufStatus);
nV = pBufStatus; //Save Copy
//CONVERT THE VALUE TO USEABLE FORM
valueV = ((int)valueV << 8) + pBufStatus[1];
valueV = ((int)valueV << 8) + pBufStatus[0];
//Multiply by 100 for formatting
valueV = valueV / 100;
newVoltage.Format("%.2f", valueV);
//Read_IIN command
pBufStatus[0] = 0x89; //Read_IIN Command
//Send Read_IIN command
MasterTxRx(I2CAddr, pBufStatus, 1, 2, 1, 120);
//Get the Voltage Reading, value is placed in pBufStatus
newPort.iPortAIGetMasterRxMsg(512, pBufStatus);
nC = pBufStatus; //Save Copy
//CONVERT THE VALUE TO USEABLE FORM
valueC = ((int)valueC << 8) + pBufStatus[1];
valueC = ((int)valueC << 8) + pBufStatus[0];
//Multiply by 100 for formatting
valueC = valueC / 100;
newCurrent.Format("%.2f", valueC);
newPower.Format("%.2f", (valueC*valueV));
//SetWindowText(VoltIn, newVoltage);
//SetWindowText(CurIn, newCurrent);
//SetWindowText(PowIn, newPower);
VoltInR = newVoltage;
CurInR = newCurrent;
PowInR = newPower;
}
#pragma endregion
#pragma region "Reading new Temperatures"
{
valueV = 0;
//READ_TEMPERATURE_1
pBufStatus[0] = 0x8D; //Read_VIN READ_TEMPERATURE_1
pBufStatus[1] = 0; //Clear out earlier command
//Send READ_TEMPERATURE_1 command
MasterTxRx(I2CAddr, pBufStatus, 1, 2, 1, 120);
//Get the Voltage Reading, value is placed in pBufStatus
newPort.iPortAIGetMasterRxMsg(512, pBufStatus);
nV = pBufStatus; //Save Copy
//CONVERT THE VALUE TO USEABLE FORM
valueV = ((int)valueV << 8) + pBufStatus[1];
valueV = ((int)valueV << 8) + pBufStatus[0];
//Multiply by 100 for formatting
valueV = valueV / 100;
newVoltage.Format("%.2f", valueV);
//SetWindowText(TempU11, newVoltage);
TempU11R = newVoltage;
valueV = 0;
//READ_TEMPERATURE_2
pBufStatus[0] = 0x8E; //Read_VIN READ_TEMPERATURE_2
pBufStatus[1] = 0; //Clear out earlier command
//Send READ_TEMPERATURE_2 command
MasterTxRx(I2CAddr, pBufStatus, 1, 2, 1, 120);
//Get the Voltage Reading, value is placed in pBufStatus
newPort.iPortAIGetMasterRxMsg(512, pBufStatus);
nV = pBufStatus; //Save Copy
//CONVERT THE VALUE TO USEABLE FORM
valueV = ((int)valueV << 8) + pBufStatus[1];
valueV = ((int)valueV << 8) + pBufStatus[0];
//Multiply by 100 for formatting
valueV = valueV / 100;
newVoltage.Format("%.2f", valueV);
//SetWindowText(TempU12, newVoltage);
TempU12R = newVoltage;
valueV = 0;
//READ_TEMPERATURE_3
pBufStatus[0] = 0x8F; //Read_VIN READ_TEMPERATURE_3
pBufStatus[1] = 0; //Clear out earlier command
//Send READ_TEMPERATURE_3 command
MasterTxRx(I2CAddr, pBufStatus, 1, 2, 1, 120);
//Get the Voltage Reading, value is placed in pBufStatus
newPort.iPortAIGetMasterRxMsg(512, pBufStatus);
nV = pBufStatus; //Save Copy
//CONVERT THE VALUE TO USEABLE FORM
valueV = ((int)valueV << 8) + pBufStatus[1];
valueV = ((int)valueV << 8) + pBufStatus[0];
//Multiply by 100 for formatting
valueV = valueV / 100;
newVoltage.Format("%.2f", valueV);
//SetWindowText(TempU13, newVoltage);
TempU13R = newVoltage;
}
#pragma endregion
for (int i = 0; i < 11; i++)
{
valueV = 0;
valueC = 0;
//FOR LOOP Index thru pages
//i = 0 +5V
//i = 1 +3.3V
//i = 2 +12V
//i = 3 -12V
//i = 4 +12V_AUX
//i = 10 +28V_Input
pBufStatus[0] = 0x00; //Page Command
pBufStatus[1] = (char)i; //Page Number
MasterTx(I2CAddr, pBufStatus, 2, 1, 60);
#pragma region "Reading new OUT Volt Cur Pow"
switch (i)
{
case 0:
case 1:
case 2:
{
//Read_VOUT
pBufStatus[0] = 0x8B; //Read_Vout Command
pBufStatus[1] = 0; //Clear out earlier command
//Send Read_VOUT command
MasterTxRx(I2CAddr, pBufStatus, 1, 2, 1, 120);
//Get the Voltage Reading, value is placed in pBufStatus
newPort.iPortAIGetMasterRxMsg(512, pBufStatus);
nV = pBufStatus; //Save Copy
//CONVERT THE VALUE TO USEABLE FORM
valueV = ((int)valueV << 8) + pBufStatus[1];
valueV = ((int)valueV << 8) + pBufStatus[0];
//Multiply by 100 for formatting
valueV = valueV / 100;
newVoltage.Format("%.2f", valueV);
//Read_IOUT command
pBufStatus[0] = 0x8C; //Read_Iout Command
//Send Read_IOUT command
MasterTxRx(I2CAddr, pBufStatus, 1, 2, 1, 120);
//Get the Voltage Reading, value is placed in pBufStatus
newPort.iPortAIGetMasterRxMsg(512, pBufStatus);
nC = pBufStatus; //Save Copy
//CONVERT THE VALUE TO USEABLE FORM
valueC = ((int)valueC << 8) + pBufStatus[1];
valueC = ((int)valueC << 8) + pBufStatus[0];
//Multiply by 100 for formatting
valueC = valueC / 100;
newCurrent.Format("%.2f", valueC);
newPower.Format("%.2f", (valueC*valueV));
break;
}
case 3:
case 4:
{
//Read_VOUT
pBufStatus[0] = 0x8B; //Read_Vout Command
pBufStatus[1] = 0; //Clear out earlier command
//Send Read_VOUT command
MasterTxRx(I2CAddr, pBufStatus, 1, 2, 1, 120);
//Get the Voltage Reading, value is placed in pBufStatus
newPort.iPortAIGetMasterRxMsg(512, pBufStatus);
nV = pBufStatus; //Save Copy
//CONVERT THE VALUE TO USEABLE FORM
valueV = ((int)valueV << 8) + pBufStatus[1];
valueV = ((int)valueV << 8) + pBufStatus[0];
//Multiply by 100 for formatting
valueV = valueV / 100;
newVoltage.Format("%.2f", valueV);
break;
}
case 10:
{
//Read_VOUT
pBufStatus[0] = 0x8B; //Read_Vout Command
pBufStatus[1] = 0; //Clear out earlier command
//Send Read_VOUT command
MasterTxRx(I2CAddr, pBufStatus, 1, 2, 1, 120);
//Get the Voltage Reading, value is placed in pBufStatus
newPort.iPortAIGetMasterRxMsg(512, pBufStatus);
nV = pBufStatus; //Save Copy
//CONVERT THE VALUE TO USEABLE FORM
valueV = ((int)valueV << 8) + pBufStatus[1];
valueV = ((int)valueV << 8) + pBufStatus[0];
//Multiply by 100 for formatting
valueV = valueV / 100;
newVoltage.Format("%.2f", valueV);
break;
}
}
#pragma endregion
#pragma region "Display reading"
switch (i) //switch on the page number, display new values and checks faults if needed
{
case 0: //+5V
{
#pragma region "5V Display"
{
//SEND OUTPUT TO WINDOW USING SetWindowText();
//SetWindowText(Volt5at24, newVoltage);
Volt5at24R = newVoltage;
//SetWindowText(Cur5at24, newCurrent);
Cur5at24R = newCurrent;
//SetWindowText(Pow5at24, newPower);
Pow5at24R = newPower;
break;
}
#pragma endregion
}
case 1: //+3.3V
{
#pragma region "3.3V Display"
{
//SEND OUTPUT TO WINDOW USING SetWindowText();
//SetWindowText(Volt3at15, newVoltage);
Volt3at15R = newVoltage;
//SetWindowText(Cur3at15, newCurrent);
Cur3at15R = newCurrent;
//SetWindowText(Pow3at15, newPower);
Pow3at15R = newPower;
break;
}
#pragma endregion
}
case 2: //+12V
{
#pragma region "12V Display"
{
//SEND OUTPUT TO WINDOW USING SetWindowText();
//SetWindowText(Volt12at1, newVoltage);
Volt12at1R = newVoltage;
//SetWindowText(Cur12at1, newCurrent);
Cur12at1R = newCurrent;
//SetWindowText(Pow12at1, newPower);
Pow12at1R = newPower;
break;
}
#pragma endregion
}
case 3: //-12V
{
#pragma region "-12V Display"
{
//SEND OUTPUT TO WINDOW USING SetWindowText();
//SetWindowText(Volt12at2, newVoltage);
Volt12at2R = newVoltage;
}
#pragma endregion
}
case 4: //+12V AUX
{
#pragma region "12V AUX Display"
{
//SEND OUTPUT TO WINDOW USING SetWindowText();
//SetWindowText(Volt12at40, newVoltage);
Volt12at40R = newVoltage;
}
#pragma endregion
}
case 10: //+28V input
{
#pragma region "3.3 HSKPR Display"
{
//SEND OUTPUT TO WINDOW USING SetWindowText();
//SetWindowText(VoltIn, newVoltage);
Volt3HR = newVoltage;
break;
}
#pragma endregion
}
}
#pragma endregion
}
#pragma endregion
}
}

C++ Pixel Grabber wrong RGB values

my pixel grabber (I modified it from online source) But the RGB values are off.. Could someone take a look at this, and maybe fix it.
I'm trying to grab all pixels from the screen and turn values into RGB as fast as possible.
#include "iostream"
#include <Windows.h>
using namespace std;
HDC hdc, hdcTemp;
int x, y;
void PixelFunction(); // Get the pixel rgb function
int main()
{
PixelFunction();
ReleaseDC(HWND_DESKTOP, hdc);
cout<<"done";
getchar();
return 0;
}
void PixelFunction()
{
BYTE* bitPointer;
int red, green, blue, alpha;
hdc = GetDC(HWND_DESKTOP);
int MAX_WIDTH = GetDeviceCaps(hdc, HORZRES);
int MAX_HEIGHT = GetDeviceCaps(hdc, VERTRES);
hdcTemp = CreateCompatibleDC(hdc);
BITMAPINFO bitmap;
bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
bitmap.bmiHeader.biWidth = MAX_WIDTH;
bitmap.bmiHeader.biHeight = MAX_HEIGHT;
bitmap.bmiHeader.biPlanes = 1;
bitmap.bmiHeader.biBitCount = 32;
bitmap.bmiHeader.biCompression = BI_RGB;
bitmap.bmiHeader.biSizeImage = MAX_WIDTH * 4 * MAX_HEIGHT;
bitmap.bmiHeader.biClrUsed = 0;
bitmap.bmiHeader.biClrImportant = 0;
HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
SelectObject(hdcTemp, hBitmap2);
BitBlt(hdcTemp, 0, 0, MAX_WIDTH, MAX_HEIGHT, hdc, 0, 0, SRCCOPY);
for (int i=0; i<MAX_HEIGHT; i ++)
{
for (int ii=0; ii<MAX_WIDTH; ii++)
{
{
blue = (int)bitPointer[ii];
green = (int)bitPointer[ii+1];
red = (int)bitPointer[ii+2];
alpha = (int)bitPointer[ii+3];
cout << "Red " << red << ".\n";
cout << "Green " << green << ".\n";
cout << "Blue " << blue << ".\n";
SetCursorPos(ii, i);
Sleep(500);
}
}
}
}
You're dereferencing the bitmap pointer with nonsensical offsets.
I'm not really familiar with the bitmap file format, but you'll probably need something like:
blue = (int)bitPointer[i*MAX_WIDTH + ii];
green = (int)bitPointer[i*MAX_WIDTH + ii + 1];
red = (int)bitPointer[i*MAX_WIDTH + ii + 2];
alpha = (int)bitPointer[i*MAX_WIDTH + ii + 3];
Currently, you will only ever address the top row.