Gdiplus Bitmap error - gdi+

I'm trying to convert an HBITMAP to a Gdiplus Bitmap. My code is getting a screenshot with some code I found from google and putting it in an HBITMAP. I want to get the rgb values (specifically argb) using Gdiplus.
The code getting the screenshot works file, but the line that turns the HBITMAP into a Bitmap throws a ton of crazy linker errors. Here is my code:
HDC hScreenDC = CreateDC((LPCWSTR)"DISPLAY", NULL, NULL, NULL);
// and a device context to put it in
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
int x = GetDeviceCaps(hScreenDC, HORZRES);
int y = GetDeviceCaps(hScreenDC, VERTRES);
// maybe worth checking these are positive values
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, x, y);
// get a new bitmap
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);
BitBlt(hMemoryDC, 0, 0, 1920, 1080, hScreenDC, 0, 0, SRCCOPY);
hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);
// clean up
DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);
Gdiplus::Bitmap* pBitmap = Gdiplus::Bitmap::FromHBITMAP( hBitmap, NULL ); // <-- problem line
The liner error is a LNK2019 and says:
Error 2 error LNK2019: unresolved external symbol _GdipFree#4 referenced in function "public: static void __cdecl Gdiplus::GdiplusBase::operator delete(void *)" (??3GdiplusBase#Gdiplus##SAXPAX#Z)
I have included gdiplus.h, windows.h, and #define GDIPVER 0x110
Any idea how to fix this?

First thing to check - have you linked to gdiplus.lib? That's very likely the problem.
Also make sure that you've called GdiplusStartup() at some point before you start using the GDI+ functions.

You need to link your project to gdiplus.lib.
#include "Gdiplus.h"
#pragma comment(lib,"gdiplus.lib")
Checkout this post as an example.

Related

How can I show a memory address in QLabel?

I wanted to show a memory address in a QLabel. When I compile the following code, it give me error:
// Allocate space for our DLL path inside the target remote process.
LPVOID dll_path_in_remote_mem_addr = VirtualAllocEx(
target_process,
NULL,
_MAX_PATH,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE
);
if (dll_path_in_remote_mem_addr == NULL) {
QMessageBox::warning(this, "Failed OPS", "Allocating space for our DLL path in the remote target process's virtual memory space failed...");
CloseHandle(target_process);
}
else
{
ui->labelDllAllocationAddress->setText(&dll_path_in_remote_mem_addr);
}
After compilation process, it shows me the following error:
error: C2664: 'void QLabel::setText(const QString &)': cannot convert argument 1 from 'LPVOID *' to 'const QString &'
How can I show a memory address of LPVOID type in widget like QLabel?
First you need to convert your address to a QString type. As it is an address, you probably want to see it in its hexadecimal form :
EDIT : as the LPVOID value is not implicitly cast to an int, you need to do it yourself.
EDIT2 : the long type is not big enough to hold the pointer (64-bit machine), so you need to use long long.
unsigned long address = reinterpret_cast<long long>(dll_path_);
QString addressInTextValue = QString("%1").arg(address, 0, 16);
This is documented here : https://doc.qt.io/qt-5/qstring.html

How to solve undefined references, is the library not imported, or other problems

I'm trying to use Win32 GUI project on a project, but when I compile it, I get a lot of undefined reference errors.
||=== Build: Debug in 05.9.finally (compiler: GNU GCC Compiler) ===|
obj\Debug\main.o||In function Z4OpenP6HWND__':|
C:\Users\Administrator\Desktop\计算机图形\05.9.finally\main.cpp|61|undefined
reference towglCreateContext#4'|
C:\Users\Administrator\Desktop\计算机图形\05.9.finally\main.cpp|63|undefined
reference to wglMakeCurrent#8'|
C:\Users\Administrator\Desktop\计算机图形\05.9.finally\main.cpp|65|undefined
reference toglClearColor#16'| obj\Debug\main.o||In function
Z4Initv':|
C:\Users\Administrator\Desktop\计算机图形\05.9.finally\main.cpp|76|undefined
reference toglBlendFunc#8'|
C:\Users\Administrator\Desktop\计算机图形\05.9.finally\main.cpp|77|undefined
reference to glClearColor#16'|
C:\Users\Administrator\Desktop\计算机图形\05.9.finally\main.cpp|78|undefined
reference toglClearDepth#8'|
C:\Users\Administrator\Desktop\计算机图形\05.9.finally\main.cpp|79|undefined
reference to glDepthFunc#4'|
C:\Users\Administrator\Desktop\计算机图形\05.9.finally\main.cpp|80|undefined
reference toglEnable#4'|
C:\Users\Administrator\Desktop\计算机图形\05.9.finally\main.cpp|81|undefined
reference to glShadeModel#4'|
C:\Users\Administrator\Desktop\计算机图形\05.9.finally\main.cpp|82|undefined
reference toglHint#8'| obj\Debug\main.o||In function `Z6Draw3Dv':|
#include <GL/gl.h>
#include <GL/glut.h>
#include <windows.h>
GLfloat step = 0.0f;
HINSTANCE hInstance; // 系统实例句柄
HWND hWndMain; // 主窗体句柄
HWND hWnd; // 窗体句柄变量定义
HDC hDC; // 设备描述表变量定义
PIXELFORMATDESCRIPTOR pfd; // 像素格式结构变量定义
HGLRC hGLRC; // OpenGL渲染描述表变量定义
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // 窗体过程函数声明
GLboolean keys[256];
GLfloat rotStep = 30.0f;
void keyPress();
GLuint Open(HWND phWnd)
{
hWnd = phWnd;
hDC = GetDC(hWnd);
pfd.dwDamageMask = 0; // 忽略层遮罩
int pixelformat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, pixelformat, &pfd);
hGLRC = wglCreateContext(hDC);
wglMakeCurrent(hDC,hGLRC);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // 初始化背景为灰色
return 0;
}
You includes have a forward slash in the naming. Maybe you wanted #include "path/name".
I believe you would have solved it by now; in case not then you can try providing correct library path. Use command line options -L for path to library folder and -l for library name while compiling/linking.
An online lookup for OpenGL suggests the library file names may be any or all from these: opengl32.a or opengl32.lib, glu32.a or glu32.lib, freeglut.a or freeglut.lib (choose .a if you are building on Linux or .lib on Windows).

Qstring to LPCWSTR

LPCWSTR path;
void WinApiLibrary::StartProcess(QString name)
{
path = name.utf16();
CreateProcess(path, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
}
C:\kursovaya\smc\winapilibrary.cpp:21: error: invalid conversion from
'const ushort* {aka const short unsigned int*}' to 'LPCWSTR {aka const
wchar_t*}' [-fpermissive]
path = name.utf16();
This code worked in the Qt 4.8, but now i have Qt 5.2 and this code isn't working. What's wrong with this guy?
I had the same issue (I'm using Qt 5.3), this is how I fixed it:
QString strVariable1;
LPCWSTR strVariable2 = (const wchar_t*) strVariable1.utf16();
QString::utf16() returns const ushort*, which is different from const wchar_t*, so you have the compile error.
You are probably compiling with /Zc:wchar_t. If you change it to /Zc:wchar_t- it should work, as wchar_t type becomes typedef to 16-bit integer in this case.
In Visual Studio: Project Properties->Configuration Properties->C/C++->Treat WChar_t As Built in Type->No.
Or just add reinterpret_cast<LPCWSTR>.
I'm using Qt 5.2 and I had the same issue. This is how I fixed it:
QString sPath = "C:\\Program File\\MyProg";
wchar_t wcPath[1024];
int iLen = sPath.toWCharArray(wcPath);
In the Qt global namespace, there is the macro qUtf16Printable. However as the documentation states, this produces a temporary so take care to use it properly. Note this was introduced in Qt5.7.

Extracting icon using WinAPI in Qt app

I'm trying to extract icon from exe file using WinAPI, but it doesn't work.
Here's the code:
QIcon OSTools::AppsInterface::extractAppIcon(const QString &fileName) const {
wchar_t *convertedName = new wchar_t[fileName.length() + 1];
fileName.toWCharArray(convertedName);
convertedName[fileName.length()] = '\0';
HICON Icon = ExtractIcon(NULL, convertedName, 0);
QPixmap pixmap = QPixmap::fromWinHICON(Icon);
return QIcon(pixmap);
}
Code outputs:
QPixmap::fromWinHICON(), failed to GetIconInfo()
(ExtractIcon function on MSDN).
I think problem is that I send NULL instead of "A handle to the instance of the application calling the function". But, generally, I use Qt, and it's only one WinAPI function in my app.
What's wrong? What's correct way to extract icon using WinAPI? If you have another function proposal, please, give me an example. This is the first time I'm using WinAPI.
UPDATE: Yes, there is a better way. You may use QFileIconProvider class for doing such things.
Works for me, even with NULL. But obtaining the HINSTANCE is actually very simple. You have a problem elsewhere i guess. Does your target exe really have an embedded icon?
#ifdef Q_WS_WIN
#include <qt_windows.h>
#endif
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
#ifdef Q_WS_WIN
QString fileName("D:\\_dev\\eclipse\\eclipse.exe");
wchar_t *convertedName = new wchar_t[fileName.length() + 1];
fileName.toWCharArray(convertedName);
convertedName[fileName.length()] = '\0';
HINSTANCE hInstance = ::GetModuleHandle(NULL);
HICON Icon = ::ExtractIcon(hInstance, convertedName, 0);
ui->label->setPixmap(QPixmap::fromWinHICON(Icon));
#endif
}
I used QFileIconProvider, and it worked perfectly. Try this :
QPushButton b;
b.show();
QIcon icon;
QFileIconProvider fileiconpr;
icon = fileIconProvider.icon(QFileInfo("/*file name*/"));
b.setIcon(icon);
// And you can also save it where you want :
QPixmap pixmap = icon.pixmap( QSize(/*desired size*/) );
pixmap.save("/Desktop/notepad-icon.png");
Source. Have a nice day.
And solution was very simple. I just sent path to '.lnk' file instead of path to file. That's my inattention.

force call to QString(const char *) constructor in Qt 4.7

I am trying to compile a library written in Qt 4.6. On my current Linux machine I have only Qt 4.7 installed. The following code part:
/*file try.h*/
void fileOpen(QString s = NULL) ;
/*file try.cpp*/
void MainWindow::fileOpen(QString s) {
QString filename ;
if(s.isNull()) filename = QFileDialog::getOpenFileName(
this,
"Choose a file",
".",
"Source file (*.)");
else filename = s ;
}
compiles with the following error (I used cmake but the corresponding line code is the one listed above):
In member function ‘virtual int MainWindow::qt_metacall(QMetaObject::Call, int,
void**)’:
/homes/combi/hodorog/Developments/axelOld/build/axel/src/QGui/moc_MainWindow.cxx:141:26:
error: conversion from ‘long int’ to ‘QString’ is ambiguous
/homes/combi/hodorog/Developments/axelOld/build/axel/src/QGui/moc_MainWindow.cxx:141:26:
note: candidates are:
/usr/include/QtCore/qstring.h:426:43: note: QString::QString(const char*)
/usr/include/QtCore/qstring.h:105:14: note: QString::QString(const QChar*)
So I am guessing the problem is that in qt. 4.7. there are two QString constructors that can take a pointer as an argument (as listed in the compilation error), whereas in qt 4.6. there is only one QString constructor that can take a pointer as an argument. How can I force QString to call the constructor with const char * as an argument?
Thank a lot for your help in advance,
madalina
void fileOpen(QString s = NULL);
You are trying to construct a QString object with 0. It seems you are confusing the null of pointers with a null QString. A null QString is one which is created with the constructor QString(). Given how your function is implemented (referring to s.isNull()), you should change the function declaration to
void fileOpen(QString s = QString());

Resources