Connect a display in c++ - c++

I need some help in working out how to enable a display in c++ with the displays preferred settings. From what I have gathered I should use SetDisplayConfig to do this.
My code so far:
UINT32 NumPathArrayElements = 0;
UINT32 NumModeInfoArrayElements = 0;
LONG error = GetDisplayConfigBufferSizes(QDC_ALL_PATHS,&NumPathArrayElements,&NumModeInfoArrayElements);
std::vector<DISPLAYCONFIG_PATH_INFO> PathInfoArray(NumPathArrayElements);
std::vector<DISPLAYCONFIG_MODE_INFO> ModeInfoArray(NumModeInfoArrayElements);
error = QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS,&NumPathArrayElements, &PathInfoArray[0],&NumModeInfoArrayElements, &ModeInfoArray[0],NULL);
for(unsigned int i=0;i<PathInfoArray.size();++i){
if(PathInfoArray[i].sourceInfo.modeInfoIdx<ModeInfoArray.size()){
int modeIndex=PathInfoArray[i].sourceInfo.modeInfoIdx;
if(itIsADisplayIWantToWorkWith){
//Disable
//PathInfoArray[i].flags=0;
//Modify
//ModeInfoArray[modeIndex].sourceMode.position.x=-1920;
//Enable...?!
}
}
}
//Save
SetDisplayConfig(NumPathArrayElements, &PathInfoArray[0],NumModeInfoArrayElements, &ModeInfoArray[0],(SDC_APPLY | SDC_ALLOW_CHANGES | SDC_USE_SUPPLIED_DISPLAY_CONFIG));
Any form of clue as to where to look for this is appreciated, I don't feel like mixing ChangeDisplaySettingsEx(managed to enable the display with hard coded settings) with SetDisplayConfig unless I am forced to.
MSDN docs: http://msdn.microsoft.com/en-us/library/hh285671%28v=VS.85%29.aspx

Related

PrintDlgEx invalid argument, while PrintDlg works

Problem: I need to get PrintDlgEx working for my project, but no combination of options or arguments works for me. It gives E_INVALIDARG for any combinations of options, as the ones I copied from Microsoft samples or other online samples.
Replacing PRINTDLGEX with PRINTDLG and PrintDlgEx with PrintDlg (and eliminating the group of options only from PRINTDLGEX) works fine.
Unfortunately I need PrintDlgEx, because I really need the Apply button, to change printers or property sheet without printing, for design and preview.
Please help me find why I can't get the dialog to show.
Code: while I simplified pieces, like what should happen on successful return, or setting DEVMODE and DEVNAMES, I tried this function exactly, with the same result: Invalid Argument.
#include <QDebug>
#include <QWindow>
#include <windows.h>
void showPrintDialog()
{
// Simplifying the setup: real code passes in a QWidget *
QWidget *caller = this;
// Not returning a value or doing any work. I just want the dialog to pop up for now
// Create the standard windows print dialog
PRINTDLGEX printDialog;
memset(&printDialog, 0, sizeof(PRINTDLGEX));
printDialog.lStructSize = sizeof(PRINTDLGEX);
printDialog.Flags = PD_RETURNDC | // Return a printer device context. Without this, HDC may be undefined
PD_USEDEVMODECOPIESANDCOLLATE |
PD_NOSELECTION | // Don't allow selecting individual document pages to print
PD_NOPAGENUMS | // Disables some boxes
PD_NOCURRENTPAGE | // Disables some boxes
PD_NONETWORKBUTTON | // Don't allow networking (but it show "Find printer") so what does this do ?
PD_HIDEPRINTTOFILE; // Don't allow print to file
// Only on PRINTDLGEX
// Theis block copied from https://learn.microsoft.com/en-us/windows/win32/dlgbox/using-common-dialog-boxes?redirectedfrom=MSDN
// I have tried multiple combinations of options, including none, I really don't want any of them
printDialog.nStartPage = START_PAGE_GENERAL;
printDialog.nPageRanges = 1;
printDialog.nMaxPageRanges = 10;
LPPRINTPAGERANGE pageRange = (LPPRINTPAGERANGE) GlobalAlloc(GPTR, 10 * sizeof(PRINTPAGERANGE));
printDialog.lpPageRanges = pageRange;
printDialog.lpPageRanges[0].nFromPage = 1;
printDialog.lpPageRanges[0].nToPage = 1;
printDialog.Flags2 = 0;
printDialog.ExclusionFlags = 0;
printDialog.dwResultAction = 0; // This will tell me if PRINT
// Rest of options are also on PRINTDLG
printDialog.nMinPage = 1;
printDialog.nMaxPage = 10;
// The only options I really need
printDialog.nCopies = 1;
printDialog.hDevMode = Q_NULLPTR; // which will be better once this works
printDialog.hDevNames = Q_NULLPTR; // which will be better once this works
printDialog.hwndOwner = reinterpret_cast<HWND>(caller->windowHandle()->winId());
// Calling...
int result = PrintDlgEx(&printDialog);
qDebug() << (result == E_INVALIDARG ? "Invalid Argument\n" : "Success\n");
// It always is E_INVALIDARG
// Cleanup
if (printDialog.hDevMode)
GlobalFree(printDialog.hDevMode);
if (printDialog.hDevNames)
GlobalFree(printDialog.hDevNames);
if (printDialog.hDC)
DeleteDC(printDialog.hDC);
}
Platform: Windows 10, latest update;
Qt version: 5.12.7 or higher
(since in VM I have 5.15.1)
The fact that I am running in Qt should be irrelevant, since this is all WIN API, beyond the c++ version (11)
I can make your example work if I remove PD_NONETWORKBUTTON flag.
Please note that while it is documented for PRINTDLGA struct, it is NOT listed in PRINTDLGEXA
NOTE: I did get the same error with that flag.

C++ | How to remove the DataSource from a combobox?

I'm writing a windows forms application in visual studio with c++ and CLR.
And now, i got the following problem:
I read in a file and save all the important informations in a vector.
With a second step, i convert all items to a CLR array and set this array as DataSource.
array<System::String^>^ PREDEFINED = gcnew array <System::String^>(OP->CIS_Values[OP->selectedCIS]->PREDEFINED_order.size());
for (int i = 0; i < OP->CIS_Values[OP->selectedCIS]->PREDEFINED_order.size(); i++) {
PREDEFINED[i] = msclr::interop::marshal_as<System::String^>(OP->CIS_Values[OP->selectedCIS]->PREDEFINED_order[i]);
}
this->comboBox_header_predefinedtypes->DataSource = PREDEFINED;
this->comboBox_header_predefinedtypes->SelectedIndex = -1;
delete PREDEFINED;
After setting the DataSource, it must be possible to remove it. In C# i can do this with
comboBox.DataSource = null;
but how does it work in C++?
I tried the following cases:
comboBox_header_predefinedtypes->DataSource = NULL;
comboBox_header_predefinedtypes->DataSource = 0;
comboBox_header_predefinedtypes->DataSource = -1;
comboBox_header_predefinedtypes->DataBindings->Clear();
comboBox_header_predefinedtypes->Items->Clear();
I tried it with DataBindings before and after DataSource, but i always get the same exception:
System.ArgumentException: "The complex DataBinding accepts as a data source either IList or IListSource"
How can i fix this issue ?
Thx for help.
In C++ CLR you only need to write:
comboBox_header_predefinedtypes->DataSource = nullptr;
and you don't need to write
comboBox_header_predefinedtypes->Items->Clear();
after removing the DateSource to delete the items.

Changing Mavlink Message Rate ArduPilotMega

I am working on a project that uses Mavlink protocol (in c++) to communicate with the ArduPilotMega (2.6).
I am able to read messages such as ATTITUDE for example. The current message rate (for all messages) is 2Hz and I would like to increase this rate.
I found out that I should probably set MESSAGE_INTERVAL using MAV_CMD_SET_MESSAGE_INTERVAL in order to change it.
So my question is:
How do I send this command message using mavlink in c++?
I tried doing it using the code below but it did not work. I guess I have to use the command I mentioned above, but I don't know how.
mavlink_message_t command;
mavlink_message_interval_t interval;
interval.interval_us = 100000;
interval.message_id = 30;
mavlink_msg_message_interval_encode(255, 200, &command, &interval);
p_sensorsPort->write_message(command);
Update: I also tried this code below, maybe I am not giving it the right system id or component id.
mavlink_message_t command;
mavlink_command_long_t interval;
interval.param1 = MAVLINK_MSG_ID_ATTITUDE;
interval.param2 = 100000;
interval.command = MAV_CMD_SET_MESSAGE_INTERVAL;
interval.target_system = 0;
interval.target_component = 0;
mavlink_msg_command_long_encode(255, 0, &command, &interval);
p_sensorsPort->write_message(command);
Maybe I am missing something about the difference between target_system, target_component and sysid, compid. I tried few values for each but nothing worked.
Is there any ACK that will be able to tell me if it even got the command?
I guess you missed start_stop field. the below sample is working.
final msg_request_data_stream msg = new msg_request_data_stream ();
msg.req_message_rate = rate;
msg.req_stream_id = (short) streamId;
msg.target_component = (short)compID;
msg.target_system = (short)sysID;
/*
GCS_COMMON.cpp contains code that sends when value =1
and stop when value = 0
that is it.
*/
if (rate > 0) {
msg.start_stop = 1;
} else {
msg.start_stop = 0;
}
From Robotis Stack Exchange answer,
In order to change the message rate, the simplest way is to change the SR_* parameters value using Mission Planner. The maximum rate is 10Hz.
For example, in order to change the ATTITUDE message rate to be 10Hz I just had to change the SR_EXTRA1 parameter to be 10.
For more information about which parameter changes each message see GCS_Mavlink.cpp file in ArduCopter firmware.

C++: Disabling RequireCHAP and RequireMsCHAP2 in the Windows RAS API

I am writing a program that will set up a VPN on a user's computer. My sysadmin told me that the security page of the VPN must have these security settings checked, and no others.
I have used this code as a basis for my own. My version sets almost everything correctly, except that it cannot uncheck the 2 boxes titled Challenge Handshake Authentication Protocol (CHAP) and Microsoft CHAP Version 2 (MS-CHAP v2). Is it possible to programmatically uncheck those 2 checkboxes while leaving the Data Encryption dropdown list set as Require Encryption? Here is my code:
void createVPN()
{
DWORD size = 0;
RasGetEntryProperties(NULL, L"", NULL, &size, NULL, NULL);
LPRASENTRY pras = (LPRASENTRY)malloc(size);
memset(pras, 0, size);
pras->dwSize = size;
pras->dwType = RASET_Vpn;
pras->dwRedialCount = 1;
pras->dwRedialPause = 60;
pras->dwfNetProtocols = RASNP_Ip;
pras->dwEncryptionType = ET_Require;
wcscpy_s(pras->szLocalPhoneNumber, L"meraki.companyname.com");
wcscpy_s(pras->szDeviceType, RASDT_Vpn);
pras->dwfOptions = RASEO_RemoteDefaultGateway;
pras->dwVpnStrategy = VS_L2tpOnly;
pras->dwfOptions2 |= RASEO2_UsePreSharedKey;
pras->dwfOptions &= ~(RASEO_RequireCHAP | RASEO_RequireMsCHAP | RASEO_RequireMsCHAP2);//This should unset the CHAP flags, but it doesn't.
RasSetEntryProperties(NULL, L"CompanyName Meraki VPN", pras, pras->dwSize, NULL, 0);
RASCREDENTIALS ras_cre_psk = { 0 };
ras_cre_psk.dwSize = sizeof(ras_cre_psk);
ras_cre_psk.dwMask = RASCM_PreSharedKey;
wcscpy_s(ras_cre_psk.szPassword, L"redacted");
RasSetCredentials(NULL, L"CompanyName Meraki VPN", &ras_cre_psk, FALSE);
free(pras);
}
I am thinking that by setting pras->dwEncryptionType to ET_Require, that prevents RASEO_RequireCHAP and the other CHAP flags from being unset, but in the Windows GUI, it is possible to uncheck them and leave Data Encryption set to Require Encryption. My sysadmin tells me that the connection will not work if either of the CHAP checkboxes are checked, or if Data Encryption is not set to Require Encryption. What can I do?
I have finally figured it out. You have to set the RASEO_RequirePAP switch. Here is the final version of the function:
void createVPN()
{
DWORD size = 0;
RasGetEntryProperties(NULL, L"", NULL, &size, NULL, NULL);
RASENTRY rasEntry = {};
rasEntry.dwSize = sizeof(rasEntry);
rasEntry.dwType = RASET_Vpn;
rasEntry.dwRedialCount = 1;
rasEntry.dwRedialPause = 60;
rasEntry.dwfNetProtocols = RASNP_Ip;
rasEntry.dwEncryptionType = ET_Require;
wcscpy_s(rasEntry.szLocalPhoneNumber, L"meraki.enoble.com");
wcscpy_s(rasEntry.szDeviceType, RASDT_Vpn);
rasEntry.dwfOptions = RASEO_RemoteDefaultGateway;
rasEntry.dwVpnStrategy = VS_L2tpOnly;
rasEntry.dwfOptions2 |= RASEO2_UsePreSharedKey;
rasEntry.dwfOptions |= RASEO_RequirePAP;
RasSetEntryProperties(NULL, L"Enoble Meraki VPN", &rasEntry, rasEntry.dwSize, NULL, 0);
RASCREDENTIALS ras_cre_psk = { 0 };
ras_cre_psk.dwSize = sizeof(ras_cre_psk);
ras_cre_psk.dwMask = RASCM_PreSharedKey;
wcscpy_s(ras_cre_psk.szPassword, L"passport2k");
RasSetCredentials(NULL, L"Enoble Meraki VPN", &ras_cre_psk, FALSE);
}
I hope this helps somebody.

How to get the screen size with C++ builder (Firemonkey)

I know it is a stupid question, but when changing visual libraries I found a "throuble" with FMX...
My problem is: I need to do my own border, so I set the propriety to Border Style:"None", but the application runs in full screen, also covering the windows toolbar, so I would like a way to resize the application form according to the screen eg.:
mainForm->Height = Screen->Height - 10;
It is possible using VCL, but are there any way to do it using FMX library?
The maximum I conquested with FMX is (I don't know how does it returns values, and the kind of values):
Screen->Size(); // TSize
I've also conquested it now, but I have compiler error:
TSize* Tamanho = new TSize;
Tamanho = Screen->Size();
frmPrincipal->Width = Tamanho->Width;
frmPrincipal->Height = Tamanho->Height - 10;
Error:"E2034 Cannot covert 'TSize' to 'TSize*'"
Finally I've tried to put it on frmPrincipal.h, but the same error:
TSize *Tamanho;
PS.: Other possible solutions to solve the "main problem" are acceptable...
Thanks a LOT!
TScreen::Size() return an actual instance of the TSize struct, not a TSize* pointer. You need to change your code accordingly:
TSize Tamanho = Screen->Size();
frmPrincipal->Width = Tamanho.Width;
frmPrincipal->Height = Tamanho.Height - 10;
Alternatively, you can use FMX's Platform Services framework to access the IFMXScreenService interface directly (this is what TScreen::Size() uses internally):
_di_IInterface Intf;
if (TPlatformServices::Current->SupportsPlatformService(__uuidof(IFMXScreenService), Intf))
{
_di_IFMXScreenService Svc = Intf;
TPoint size = Svc->GetScreenSize().Round();
frmPrincipal->Width = size.X;
frmPrincipal->Height = size.Y - 10;
}