I'm trying to update some C++ code in a custom version of DOSBox from SDL1.2 to SDL2. The lines that have me baffled are these:
SDL_SysWMinfo systemInfo;
SDL_VERSION(&systemInfo.version);
if(SDL_GetWindowWMInfo(window, &systemInfo) !=1) return;
if (!::OpenClipboard(systemInfo.info.win.window)) return;
SDL_GetWindowWMInfo is defined in SDL_syswm.h this way:
typedef struct SDL_SysWMinfo SDL_SysWMinfo;
extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowWMInfo(SDL_Window * window, SDL_SysWMinfo * info);
When I try to build in Visual Studio 2010, I get this error, thrown by the third line in the code above:
1> sdlmain.cpp
1>..\src\gui\sdlmain.cpp(2966): error C2065: 'window' : undeclared identifier
I think the answer is here:
https://gamedev.stackexchange.com/questions/82068/how-can-i-obtain-a-window-handle-in-sdl-2-0-3
but I'm a beginner and can't figure out how to adapt that to my own code. If anyone is willing to help out a complete beginner, I'll be grateful.
Solved by adding the first line (as it explains clearly in the SDL wiki):
SDL_Window* window;
SDL_SysWMinfo systemInfo;
SDL_VERSION(&systemInfo.version);
if(SDL_GetWindowWMInfo(window, &systemInfo) !=1) return;
if (!::OpenClipboard(systemInfo.info.win.window)) return;
Related
I seem to have an issue with qtcreator not autocompleting my code, which is getting pretty annoying.
Currently is it not able to autocomplete when i try to use structure bindings in for loops like this..
std::vector<pair<string,AudioFile<double>>> list_of_files;
// Some init of list_of_file
for (const auto& [name,file]: this->list_of_files) // red line under this.. does seem to like structure bindings?
{
file.printSummary(); // qtcreator don't offer any autocomplete options?
}
qtcreator basically complains about everything about the code posted above..
But when I write it like this:
for (int i = 0 ; i <list_of_file.size() ; i++) // No red lines under this..
{
list_of_files[i].second.printSummary() // Autocompletes without any problems.
}
qtcreator does not complain about this code, and seem to autocomplete it just fine.. So why is it causing so many problems with c++17 style?
Any fixes for this?
A temporary solution for this seem to be something like this - which autocompletions does not complain about, and seem to suit my definition of (readability):
for ( const auto &elements : this->list_of_files)
{
auto name = std::get<0>(elements);
auto file = std::get<1>(elements);
}
I need to create a very custom widget for printing. It has to be multi-platform as well. For consistency, the widget should be similar looking in windows as in linux or mac... After studying the Qt code, which uses the Windows print dialog, I gave up trying to subclass Qt print dialog, and made my own widget.
So, now I am on step 1: populate the list of printers on the system. I added the following code, to be called on each "show()" - just in case printers on the system change during program execution - and it works, but it is extremely slow:
I create a map of index/printer, and add the default printer as index -1, to tell the widget which one it is.
QMap<int, QString> PrintController::getListOfSystemPrinters()
{
QMap<int, QString> printerNames;
#ifdef Q_OS_WIN32
#ifdef NOT_QT_4 // I tried to use "availablePrinterNames" thinking it will be faster but it actually seems slower
QPrinter currentPrinter;
QString printerName = currentPrinter.printerName();
QStringList printerNameList = QPrinterInfo::availablePrinterNames();
int index = 0;
foreach(QString printerName1, printerNameList)
{
printerNames.insert(index, printerName1);
if(printerName == printerName1)
printerNames.insert(-1, printerName1);
++index;
}
#else
QPrinter currentPrinter;
QString printerName = currentPrinter.printerName();
QList<QPrinterInfo> printers = QPrinterInfo::availablePrinters();
int index = 0;
foreach(QPrinterInfo printerInfo, printers)
{
QString printerName1 = printerInfo.printerName();
printerNames.insert(index, printerName1);
if(printerName == printerName1)
printerNames.insert(-1, printerName1);
++index;
}
#endif
#elif defined Q_OS_UNIX
#endif
return printerNames;
}
This is the slowest piece of code I have ! I don't see another way to get all printer names... But I must be doing something wrong !
The Qt 5 version is slightly slower than the Qt 4 version... Either way, they are both slow....
The call to create a QPrinterInfo is slow.
So... are there alternatives ?
How can I get the list of printer names in Windows ?
Note this must work in Qt 4.7-5.x
Get printer list asynchronously:
class Class : public QObject {
Q_OBJECT
Q_SIGNAL void hasPrinters(const QList<QPrinterInfo> &);
Q_SIGNAL void hasPrinterNames(const QStringList &);
/// This method is thread-safe
void getPrinters() {
#if QT_VERSION >= QT_VERSION_CHECK(5,3,0)
emit hasPrinterNames(QPrinterInfo::availablePrinterNames());
#else
emit hasPrinters(QPrinterInfo::availablePrinters());
#endif
}
void test() {
QtConcurrent::run(this, &Class::getPrinters);
}
};
The above compiles on Qt 4.7 & up, using either C++98 or C++11.
Connect to the hasPrinterNames/hasPrinters signal to be notified when the printer list is available, then populate your dialog.
You might be lucky and availablePrinterNames/availablePrinters will be thread-safe. I haven't checked if it is.
On Qt 5.3 and newer, only create the QPrinterInfo for a given printer once your user has selected it, and you might want to create it concurrently as well.
According to the documentation for
SDL_bool SDL_GetWindowWMInfo(SDL_Window* window,
SDL_SysWMinfo* info)
SDL_SysWMinfo* info's SDL_Version version member must be defined by the SDL_VERSION macro at compile time before it is passed.
Why does SDL_GetWindowWMInfo require the SDL version the calling code was compiled against? What would happen if SDL_GetWindowWMInfo did not check the SDL version?
It's pretty much like keltar said. This is from SDL_windowswindow.c:
SDL_bool
WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
{
const SDL_WindowData *data = (const SDL_WindowData *) window->driverdata;
if (info->version.major <= SDL_MAJOR_VERSION) {
info->subsystem = SDL_SYSWM_WINDOWS;
info->info.win.window = data->hwnd;
info->info.win.hdc = data->hdc;
return SDL_TRUE;
} else {
SDL_SetError("Application not compiled with SDL %d.%d\n",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return SDL_FALSE;
}
}
This function fills in a user-provided struct. The danger is that this struct is liable to change as the platform support in SDL changes (as opposed to actual feature/API changes that are more apparent in a new version number).
If that struct definition has changed between versions of SDL (say, you use updated headers but old dll), this requirement allows SDL to detect the problem before it stomps your program's memory.
I'm learning OpenGL programming with the book OpenGL Programming Guide. But I cannot run the examples in the book with my Macbook. There are always dozens of errors when running even dealing with the first example Triangles. I wonder what should I do to run the examples in Red Book with Xcode.
[Platform Information]
Macbook Air, OS X 10.10, Xcode 6.1
[What did I try]
1. I deleted AppDelegate.* and main.m, and then create a cpp file triangles.cpp and copy the source code into it.(The source code will be attached at the end)
2. I added OpenGL.framework.
3. I manually installed glew, and added corresponding paths to Header Search Paths and Library Search Paths. And added -lGLEW to Other Linker Flags.
4. I manually installed freeglut, added corresponding paths to Header Search Paths and Library Search Paths, and added -lGLUT to Other Linker Flags, just under the instruction of Lazy Foo's OpenGL tutorial.
5. I added the directory of the source code attached to the Red Book into Header Search Paths and Library Search Paths so Xcode can find "vgl.h" and "LoadShaders.h". And LoadShaders.cpp was added to the project.
The reason I did step 3 and 4 is to make compiling succeed, otherwise, I would receive lots of errors such as :
Undefined symbols for architecture x86_64:
"_glutInitContextProfile", referenced from:
_main in main.o
In this way, however, the compiling was OK, but there's an error when I run it:
X Error of failed request: BadRequest (invalid request code or no such operation)
Major opcode of failed request: 34 (X_UngrabKey)
Serial number of failed request: 29
Current serial number in output stream: 29
Program ended with exit code: 1
I really wonder what is the right way to run the examples in Red Book on Mac OS X!
triangles.cpp:
#include <iostream>
using namespace std;
#include "vgl.h"
#include "LoadShaders.h"
enum VAO_IDs { Triangles, NumVAOs };
enum Buffer_IDs { ArrayBuffer, NumBuffers};
enum Attrib_IDs { vPosition = 0};
GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers];
const GLuint NumVertices = 6;
void init(void)
{
glGenVertexArrays(NumVAOs, VAOs);
glBindVertexArray(VAOs[Triangles]);
GLfloat vertices[NumVertices][2] = {
{-0.90, -0.90},
{0.85, -0.90},
{-0.90, 0.85},
{0.90, -0.85},
{0.90, 0.90},
{-0.85, 0.90}
};
glGenBuffers(NumBuffers, Buffers);
glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
ShaderInfo shaders[] = {
{GL_VERTEX_SHADER, "triangles.vert"},
{GL_FRAGMENT_SHADER, "triangles.frag"},
{GL_NONE, NULL}
};
GLuint program = LoadShaders(shaders);
glUseProgram(program);
glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(vPosition);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAOs[Triangles]);
glDrawArrays(GL_TRIANGLES, 0, NumVertices);
glFlush();
}
int main(int argc, char ** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(512, 512);
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow(argv[0]);
if(glewInit())
{
cerr << "Unable to initialize GLEW ... exiting" << endl;
exit(EXIT_FAILURE);
}
init();
glutDisplayFunc(display);
glutMainLoop();
}
If you don't mind working in C# then look into OpenTK, it's an OpenGL wrapper for Mono and .Net. I haven't tried it with Xcode, but it works beautifully in Xamarin Studio.
If you go the Xamarin route, there are two options:
1) Download the latest OpenTK release and reference OpenTK.dll
2) Use the OpenTK included with Xamarin, instructions here.
I'd recommend downloading the external version, there are loads of helpful examples included.
Something to watch out for however is that on MacOS, the GameWindow constructor defaults to OpenGL 2.1 (doesn't on Windows), so if you want to use modern features you must explicitly specify the OpenGL version number in the constructor.
public Game() : base(800, 600, new GraphicsMode(new ColorFormat(8), 3, 3, 4), "Welcome To Hell", GameWindowFlags.Default, DisplayDevice.Default, 3, 0, GraphicsContextFlags.Default)
{
}
The Red Book examples won't run directly in OpenTK, but the GL calls are the same, the syntax just needs modifying. I found Neo Kabuto's blog the best for OpenTK tutorials, and after no time at all, you'll be able to re-write the Red Book code in TK.
This probably wasn't the answer you were looking for, but it's how I solved the problem.
OS : Windows 7 32 bit
Developping Tool : Visual Studio 2008
Problem :
When run at Windows 7 it's ok, but at XP there is assertion error at DEBUG mode, invisible grid control error at RELEASE mode. (like you can see it as pictures below)
Situation :
The grid control class, I used for the program, was downloaded from code-project. (I think I can't upload the file in stackoverflow? If you need it, plz tell me.)
I used to use this class in VS 6.0. It's my first time using it in VS 9.0. There was no error when I used it in VS 6.0.
There is no compiling error when I compile the program in Windows 7 and XP.
On Windows 7, it runs well both at DEBUG and RELEASE mode.
On Windows XP, running exe file in the DEBUG folder gives an assertion error. And when I run exe file in the RELEASE folder, the grid control doesn't show up.
And I also tried to compile on XP with Visual Studio to see if there is any error, but it only gives run-time error.
Error :
Debug Assertion Failed! Program : ...
File : .../gridctrl_src/gridcell.cpp
Line : 228
For information on how your program
can cause an assertion failure, see
the Visual C+ documentation on
asserts.
The below is gridcell.cpp source code at the error line.
/////////////////////////////////////////////////////////////////////////////
// CGridDefaultCell
CGridDefaultCell::CGridDefaultCell()
{
#ifdef _WIN32_WCE
m_nFormat = DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX;
#else
m_nFormat = DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX | DT_END_ELLIPSIS;
#endif
m_crFgClr = CLR_DEFAULT;
m_crBkClr = CLR_DEFAULT;
m_Size = CSize(30,10);
m_dwStyle = 0;
#ifdef _WIN32_WCE
LOGFONT lf;
GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), &lf);
SetFont(&lf);
#else // not CE
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(NONCLIENTMETRICS);
VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0));
SetFont(&(ncm.lfMessageFont));
#endif
}
Thank you in advance!!
I encountered the same issue with CGridCtrl while porting a project from VC6 to VS2012.
In your project set _WIN32_WINNT to the lowest target platform you want your application to support. That's 0x0501 for XP SP1.
No code changes should be required in CGridDefaultCell.
Related discussion on MSDN
Answer my own question...
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ...) problem
// Initially use the system message font for the GridCtrl font
NONCLIENTMETRICS ncm;
memset(&ncm,0,sizeof(NONCLIENTMETRICS));
ncm.cbSize = sizeof(NONCLIENTMETRICS);
#if (WINVER >= 0x0600)
ncm.cbSize -= 4; //<== ADD HERE!!
#endif
BOOL f = SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS), &ncm, 0);
VERIFY(f);
if(f){
memcpy (&m_LogFont, &ncm.lfMessageFont, sizeof (LOGFONT));
m_LogFont.lfHeight = -MulDiv (11, dc.GetDeviceCaps (LOGPIXELSY), 72);
m_LogFont.lfWeight = FW_NORMAL;
m_LogFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
m_LogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
m_LogFont.lfQuality = DEFAULT_QUALITY;
m_LogFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
m_LogFont.lfCharSet = ANSI_CHARSET;
_tcscpy (m_LogFont.lfFaceName, _T ("Courier New"));
}