How can I stop wxProgressDialog re-sizing? - c++

I am using a wxProgressDialog on Windows. Whenever I change the text in the dialog the dialog box re-sizes to best accommodate the text, this leads to the dialog frequently re-sizing which looks terrible.
I tried SetMinSize and SetSizeHints but these seemed to have no effect. SetSize also seems not to work.
(For info, the dialog is show progress of file transfer. As each file is transferred its full path is displayed. These vary greatly leading the continual re-sizing.)
My code is based on this code from the samples:
static const int max = 100;
wxProgressDialog dialog("Progress dialog example",
// "Reserve" enough space for the multiline
// messages below, we'll change it anyhow
// immediately in the loop below
wxString(' ', 100) + "\n\n\n\n",
max, // range
this, // parent
wxPD_CAN_ABORT |
wxPD_CAN_SKIP |
wxPD_APP_MODAL |
//wxPD_AUTO_HIDE | // -- try this as well
wxPD_ELAPSED_TIME |
wxPD_ESTIMATED_TIME |
wxPD_REMAINING_TIME |
wxPD_SMOOTH // - makes indeterminate mode bar on WinXP very small
);
bool cont = true;
for ( int i = 0; i <= max; i++ )
{
wxString msg;
// test both modes of wxProgressDialog behaviour: start in
// indeterminate mode but switch to the determinate one later
const bool determinate = i > max/2;
if ( i == max )
{
msg = "That's all, folks!\n"
"\n"
"Nothing to see here any more.";
}
else if ( !determinate )
{
msg = "Testing indeterminate mode\n"
"\n"
"This mode allows you to show to the user\n"
"that something is going on even if you don't know\n"
"when exactly will you finish.";
}
else if ( determinate )
{
msg = "Now in standard determinate mode\n"
"\n"
"This is the standard usage mode in which you\n"
"update the dialog after performing each new step of work.\n"
"It requires knowing the total number of steps in advance.";
}
// will be set to true if "Skip" button was pressed
bool skip = false;
if ( determinate )
{
cont = dialog.Update(i, msg, &skip);
}
else
{
cont = dialog.Pulse(msg, &skip);
}
// each skip will move progress about quarter forward
if ( skip )
{
i += max/4;
if ( i >= 100 )
i = 99;
}
if ( !cont )
{
if ( wxMessageBox(wxT("Do you really want to cancel?"),
wxT("Progress dialog question"), // caption
wxYES_NO | wxICON_QUESTION) == wxYES )
break;
cont = true;
dialog.Resume();
}
wxMilliSleep(200);
}
if ( !cont )
{
wxLogStatus(wxT("Progress dialog aborted!"));
}
else
{
wxLogStatus(wxT("Countdown from %d finished"), max);
}
}

Select a size for the file path display. If the path is shorter, add blanks, if longer replace with ellipses ( ... )
wxControl::Ellipsize is useful for this ( http://docs.wxwidgets.org/3.1/classwx_control.html#a0bb834cae2a8986aceddb89f84ef4ed1 )

If you want a fixed size, you need to use wxGenericProgressDialog, there doesn't seem to be any way of preventing the native dialog, used by default under the systems that support it (Vista and later), of adapting its size to its contents.

Related

button that turns off all features

I am new to coding and embedded systems and I wanted to make a button that turns off and on a LED and at the same time turn off all other futures in the system.
So far I had the button turn off and on but I cant seem to get it to also update the Potentiometer. For some reason the code would check if the button is pressed and if so then the LED would turn on and then check if the LED is on and if so then turn on the other LEDs but when I change the value of the Potentiometer( which should switch to other LEDs) it would not update and stay on the same LED. So my question is how can I put another if statement that would keep updating in the while loop?
the code that I wanted to keep updating while the first LED is on is the "else if code"
Hope that made sense.
:)
note:
I don't know if my approach is right as I am looking at the LED and not the button it self, as my code checks if the LED is on rather then if the button is pressed.
(btw its not a switch which would have made my life a lot easier :( )
#include "mbed.h"
DigitalIn userButton (PC_10);
DigitalOut led (PC_0);
bool buttonDown = false;
BusOut leds_bus (PC_1, PB_0, PA_4);
AnalogIn pot1 (PA_5);
void init_leds ();
int cntl_val = 0;
int main ()
{
cntl_val = pot1.read_u16 () / 32768;
while (true)
{
// run forever
if (userButton.read () == true)
{
// button is pressed
if (!buttonDown)
{
// a new button press
led = !led; // toogle LED
buttonDown = true; // record that the button is now down so we don't count one press lots of times
ThisThread::sleep_for (100);
}
else if (led.read () == true)
{
if (cntl_val < 1 / 3)
{
leds_bus.write (4);
}
if (cntl_val > (1 / 3) && cntl_val < (2 / 3))
{
leds_bus.write (2);
}
if (cntl_val > (2 / 3))
{
leds_bus.write (1);
}
}
}
else
{
// button isn't pressed
buttonDown = false;
}
}
}
You need to fix your math. int cntl_val is an integer so comparing it with the fractions 1/3 and 2/3 is not going to do what you expect. And cntl_val = pot1.read_u16()/32768; can set cntl_val to only 0 or 1. If the max value returned by pot.read_u16() is less than 32768 then cntl_val will only be 0.
You could maybe change cntl_val to a float but that's probably not the best option.
Instead, try setting cntl_val = pot1.read_u16(); (don't divide by 32768). And then compare cntl_val with (32768/3) and (32768*2/3). That's still ugly but better.
It is not clear from your description, but I am assuming that you have:
An on/off indicator LED
A three-LED level indicator
A momentary action button for on/off control
A potentiometer to control the input level.
And that when the system is in the "on" state you wish to indicate the potentiometer level on the level indicator? That being the case, I suggest:
Deal with button input/debounce separately from LED state determination.
Simplify the level setting; you have a level 0, 1 or 2 which you can calculate by unsigned level = (InputLevel * 3) / 32768 ;. You can then use that level value in a bit-shift (1 << level) to determine the LED to be set. Note that you had the low level set the high bit in your LED level indicator - that would require (4 >> level), which is somewhat clumsy if you were to ever increase the number of LEDs. It is easier to reverse the order of the GPIO in the BusOut object.
Additional advice:
Apply the rule of "minimal scope", localising variables to the minimum necessary scope (you have a number of unnecessary globals.
In "big-loop" scheduling, avoid thread delays during which useful work might otherwise be done. Your debounce delay unnecessarily determines the rate at which other work can be done in the loop. The advice would be different if you were polling the button and setting the LEDs in separate threads.
For example (not this is coded blind/untested - treat it as illustrative of the general principles - it may need debugging):
#include "mbed.h"
int main ()
{
static const unsigned DEBOUNCE_MS = 20u ;
static const unsigned NUMBER_OF_LEVELS = 3u ;
DigitalIn OnOffButton( PC_10 ) ;
DigitalOut OnOffLed( PC_0 ) ;
BusOut LevelIndicator( PA_4, PB_0, PC_1 ) ;
AnalogIn InputLevel( PA_5 ) ;
bool isOn = false ;
int previous_button_state = OnOffButton ;
std::uint64_t button_change_time = 0 ;
for(;;)
{
// If debounce time expired check for button state change
if( Kernel::get_ms_count() - button_change_time > DEBOUNCE_MS )
{
int current_button_state = OnOffButton ;
// If button state changed
if( current_button_state != previous_button_state )
{
// If button-down
if( current_button_state != 0 )
{
// Toggle isOn
isOn = !isOn ;
}
// Change of state and debounce update
previous_button_state = current_button_state ;
button_change_time = Kernel::get_ms_count() ;
}
}
// Set the LEDs depending on On/Off state and input level
if( isOn )
{
OnOffLed = 1 ;
// Set level indicator
LevelIndicator = 1 << (InputLevel.read_u16() * NUMBER_OF_LEVELS / 32768u) ;
}
else
{
// System inactive (Off)
LevelIndicator = 0 ;
OnOffLed = 0 ;
}
}
}
You might also consider separating out the button and indicator processing into separate functions to increase cohesion, minimise coupling, simplify testing and improve maintainability and comprehensibility.
#include "mbed.h"
void updateIndicators( bool isOn ) ;
bool getOnOffState() ;
int main ()
{
for(;;)
{
updateIndicators( getOnOffState() ) ;
}
}
bool getOnOffState()
{
static const unsigned DEBOUNCE_MS = 20u ;
static DigitalIn OnOffButton( PC_10 ) ;
static bool state = false ;
static int previous_button_state = OnOffButton ;
static std::uint64_t button_change_time = 0 ;
// If debounce time expired check for button state change
if( Kernel::get_ms_count() - button_change_time > DEBOUNCE_MS )
{
int current_button_state = OnOffButton ;
// If button state changed
if( current_button_state != previous_button_state )
{
// If button-down
if( current_button_state != 0 )
{
// Toggle isOn
state = !state ;
}
// Change of state and debounce update
previous_button_state = current_button_state ;
button_change_time = Kernel::get_ms_count() ;
}
}
return state ;
}
void updateIndicators( bool isOn )
{
static const unsigned NUMBER_OF_LEVELS = 3u ;
static DigitalOut OnOffLed( PC_0 ) ;
static BusOut LevelIndicator( PA_4, PB_0, PC_1 ) ;
static AnalogIn InputLevel( PA_5 ) ;
// Set the LEDs depending on On/Off state and input level
if( isOn )
{
OnOffLed = 1 ;
// Set level indicator
LevelIndicator = 1 << (InputLevel.read_u16() * NUMBER_OF_LEVELS / 32768u) ;
}
else
{
// System inactive (Off)
LevelIndicator = 0 ;
OnOffLed = 0 ;
}
}

C++ call functions internally

I'm working with following code which gives access to low level monitor configuration using Windows APIs
https://github.com/scottaxcell/winddcutil/blob/main/winddcutil/winddcutil.cpp
And I would like to create a new function that increases or decreases the brightness, I was able to do this using Powershell but since the C++ code looks somewhat easy to understand I want to have a crack at it and try my luck and hopefully integrate it with an ambient light sensor later.
The powershell code I have is as follows which works with above executable: (its very crude at this stage)
$cb = [int]([uint32]("0x" + ((C:\Users\Nick\WindowsScripts\winddcutil-main\x64\Release\winddcutil.exe getvcp 0 10) -join "`n").split(" ")[2]))
if ($args[0] -eq "increase") {
if ( $cb -ne 100) {
$nb = "{0:x}" -f ($cb + 10)
C:\Users\Nick\WindowsScripts\winddcutil-main\x64\Release\winddcutil.exe setvcp 0 10 $nb
}
} elseif ($args[0] -eq "decrease") {
if ( $cb -ne 10) {
$nb = "{0:x}" -f ($cb - 10)
C:\Users\Nick\WindowsScripts\winddcutil-main\x64\Release\winddcutil.exe setvcp 0 10 $nb
}
}
It gets current brightness and if argument given is "increase" and if brightness is not already 100 then adds 10, in case of "decrease" it subtracts 10. Values are coveted to and from hex to decimals.
I understand if I want to integrate this inside the C++ code directly I would have something like following:
int increaseBrightness(std::vector<std::string> args) {
size_t did = INT_MAX;
did = std::stoi(args[0]);
//0 is monitor ID and 10 is the feature code for brightness
//currentBrightness = getVcp("0 10")
//calculate new value
//setVcp("0 10 NewValue")
}
Ultimetaly I would like to call the executable like "winddcutil.exe increasebrightness 0" (0 being the display ID)
I can keep digging around on how to do the calculation in C++ but internally calling the functions and passing the arguments so far turned out to be very challenging for me and I would appreciate some help there.
you need to add a needed option here
line 164
std::unordered_map<std::string,std::function<int(std::vector<std::string>)>> commands
{
{ "help", printUsage },
{ "detect", detect},
{ "capabilities", capabilities },
{ "getvcp", getVcp },
{ "setvcp", setVcp},
{"increasebrightness ", increaseBrightness } // update here
};
to get current brightness you can't use getVcp api due to its result will be printed to stdout , it isn't returned via returned value, follow getVcp to get brighness value , use this
DWORD currentValue;
bool success = GetVCPFeatureAndVCPFeatureReply(physicalMonitorHandle, vcpCode, NULL, &currentValue, NULL);
if (!success) {
std::cerr << "Failed to get the vcp code value" << std::endl;
return success;
}
then
define your increaseBrightness like
int increaseBrightness(std::vector<std::string> args) {
size_t did = INT_MAX;
did = std::stoi(args[0]);
DWORD currentBrightness;
bool success = GetVCPFeatureAndVCPFeatureReply(
physicalMonitorHandle, vcpCode, NULL, &currentBrightness, NULL);
if (!success) {
std::cerr << "Failed to get the vcp code value" << std::endl;
return success;
}
//example + 10
auto newValue = did + 10;
success = setVcp({"0", "10", std::to_string(newValue)});
if(success)
{
// your handler
}
// 0 is monitor ID and 10 is the feature code for brightness
// currentBrightness = getVcp("0 10")
// calculate new value
// setVcp("0 10 NewValue")
}
test for passing argument:
https://godbolt.org/z/5n5Gq3d7e
note: make sure your have increaseBrightness's declaration before std::unordered_map<std::string,std::function<int(std::vector<std::string>)>> commands to avoid compiler's complaint

How to get resolution of camera

How to get the resolution of camera? Can somebody give me some suggestion.
Only i can do is the following,but it takes too much time to get the resolution.
The code's sequence look like this:
a.Open the camerra
b.Change the camera's resolution, and check the reuslt
void GetResolution( const int& countOfCamera, resolution_t (&resoulationTemp)[MAX_RESOLUTION] ){
VideoCapture *pVideoCaptures[MAX_CAMERA] = {NULL};
bool ret1 = false;
bool ret2 = false;
for ( int j=0; j<countOfCamera; ++j ) {
pVideoCaptures[j] = new VideoCapture(j);
/*==========================================================================
*If we don't do this, we will not open the Camera correctly
===========================================================================*/
pVideoCaptures[j]->set( CV_CAP_PROP_FRAME_WIDTH, defaultResolution.width );
pVideoCaptures[j]->set ( CV_CAP_PROP_FRAME_HEIGHT, defaultResolution.height );
}
for ( int i=0; i<MAX_RESOLUTION; ++i ) {
for ( int j=0; j<countOfCamera; ++j ) {
ret1 = pVideoCaptures[j]->set( CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width );
ret2 = pVideoCaptures[j]->set ( CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height );
if ( !(ret1 && ret2) ) { //The resolution is not OK
break; //Check the next resolution
} else if ( j == ( countOfCamera -1 ) ) { //The resolution is OK for all camera,then store it.
resoulationTemp[i].width = resolutions[i].width;
resoulationTemp[i].height = resolutions[i].height;
} else {
//Do nothing
}
}
}
for ( int j=0; j<countOfCamera; ++j ) //Release the memory
{
pVideoCaptures[j]->release();
delete pVideoCaptures[j];
pVideoCaptures[j] = NULL;
}
}
Unfortunately there is no convenient way to get supported resolutions list for the particular camera by the opencv API (as it supports so many platforms and so many video capturing backends). Even your code will suffer from this, read the sources of videoio.hpp. But most of the digital video devices supports standard resolutions, you can simply select from them. Another way to get actual list of supported formats is to use 3rd party libraries, for the instance Qt solves this task by the couple of calls.

ToUnicodeEx not printing "Greater Than"

I wrote a function which processes the user keyboard in order to write text in an app.
In order to do that I use the ToUnicodeEx function which uses an array of Key states.
The function is working perfectly fine for every possible input, except for one : I cannot display the ">" sign, which is supposed to be the combination of "SHIFT + <" : it displays the "<" sign instead, as if the SHIFT key was not pressed, whereas it knows it it pressed.
Has somebody already experienced the same and knows what the problem is?
You will find my function code below :
void MyFunction(bool bCapsLockDown)
{
IOClass io = GetMyIOInstance();
HKL layout = GetKeyboardLayout( 0 );
uchar uKeyboardState[256];
WCHAR oBuffer[5] = {};
//Initialization of KeyBoardState
for (uint i = 0; i < 256; ++i)
{
uKeyBoardState[i] = 0;
}
// Use of my ConsultKeyState to get the status of pressed keys
if ( ConsultKeyState( VK_SHIFT ) || bCapsLockDown )
{
uKeyboardState[VK_CAPITAL] = 0xff;
}
if ( ConsultKeyState( VK_CONTROL ) )
{
uKeyboardState[VK_CONTROL] = 0xff;
}
if ( ConsultKeyState( VK_MENU ) )
{
uKeyboardState[VK_MENU] = 0xff;
}
if ( ConsultKeyState( VK_RMENU ) )
{
uKeyboardState[VK_MENU] = 0xff;
uKeyboardState[VK_CONTROL] = 0xff;
}
for ( uint iVK = 0; iVK < 256; ++iVK )
{
bool bKeyDown = ConsultKeyState( iVK ) != 0;
uint iSC = MapVirtualKeyEx( iVK, MAPVK_VK_TO_VSC, layout );
bool bKeyAlreadyDown = io.KeysDown[iVK];
io.KeysDown[iVK] = bKeyDown;
if ( io.KeysDown[iVK] && bKeyAlreadyDown == false )
{
int iRet = ToUnicodeEx( iVK, iSC, uKeyboardState, (LPWSTR)oBuffer, 4, 0, layout );
if( iRet > 0 && (iswgraph( (unsigned short) oBuffer[0] ) || oBuffer[0] == ' ') )
io.AddInputCharacter( (unsigned short) oBuffer[0] );
}
}
}
Edit :
To summarize, my question is :
What would be the good combination VirtualKey + KeyBoardState to get a ">" displayed?
The problem is that shift and caps lock do not have the same effect on a keyboard. For example, (on a UK keyboard) pressing shift+1 = !, but pressing 1 with caps lock on still give you 1.
Your code currently treats them the same, though, and it is using VK_CAPITAL in both cases. This will give you the same effect as if caps lock were on, which is not what you want in this case.
The solution is therefore to break out your logic and use VK_SHIFT when you really want shift to be pressed and VK_CAPITAL when you want caps lock to be active.

Maya API - Move CV with Kinect

I’m trying to create a 64-bit plug-in for Autodesk Maya 2013. The aim of this plug-in is to be able to model objects through the Kinect.
In context, with the plug-in you can select the CV of a created object. To specify you want to move the selected points, the position of selected CV is updated constantly.
Here is my problem, when I try to update the position of a selected CV of an object, the result is not displayed on the screen.
I have tried many ways without getting any result, as an example:
1) when I do the setPosition the point doesn’t update.
for ( ; !iter.isDone(); iter.next() ) {
iter.getDagPath( mdagPath, mComponent );
MItSurfaceCV sCvFn( mdagPath, mComponent, true, &stat );
if ( MS::kSuccess == stat ) {
for ( ; !sCvFn.isDone(); sCvFn.nextRow() ) {
for ( ; !sCvFn.isRowDone(); sCvFn.next() ) {
MPoint pto(pHand.posX, pHand.posY, pHand.posZ);
sCvFn.setPosition(pto, MSpace::kWorld);
}
}
}
sCvFn.updateSurface();
}
2) in this case, if you iterate over the array newCVS before doing the setCVs you can see the updated points.
But then, when doing setCVs and looking for the position in the CV array of the object (doing a getCVs) the position of the modified CV doesn’t change.
for ( ; !iter.isDone(); iter.next() ) {
stat = iter.getDagPath( mdagPath, mComponent );
if(stat == MS::kSuccess) {
MFnNurbsSurface surf(mdagPath);
MItSurfaceCV sCvFn( mdagPath, mComponent, true, &stat );
MPointArray currentCV;
surf.getCVs(currentCV, MSpace::kWorld);
MPointArray newCVS(currentCV.length(), MPoint::origin);
newCVS.setLength(currentCV.length());
for(unsigned i = 0; i < currentCV.length(); i++){
newCVS[i] = newCVS[i] + currentCV[i];
}
int index;
if ( MS::kSuccess == stat ) {
for ( ; !sCvFn.isDone(); sCvFn.nextRow() ) {
for ( ; !sCvFn.isRowDone(); sCvFn.next() ) {
sCvFn.getIndex(indexU, indexV);
int posArray = indexU * surf.numCVsInV() + indexV;
index = posArray;
MVector diff = MPoint(pHand.posX, pHand.posY, pHand.posZ) - currentCV[posArray];
newCVS[posArray] = newCVS[posArray] + diff;
}
}
surf.setCVs(newCVS, MSpace::kWorld);
surf.updateSurface();
}
}
3) When having CV selected in Maya, I tried to move this points with MEL commands. For this, I use the “MGlobal::executeCommand” function, but still nothing happens.
Finally, I changed executeCommand to executeCommandOnIdle. In this case, the object change correctly but the procedure crashes, perhaps, because this procedure is executed many times per second.
I would appreciate if anyone can help me with this problem or knows something about this.