VCL controls disappearing when a TProgressBar is being painted
I have a simple dialogue, which contains two TProgressBar
controls and two TStaticText
controls. The dialogue looks like this:
When I start painting the two progress bars, the two static text controls disappear (and reappear after the painting has finished).
The code doing the painting (probably irrelevant but here it is all the same)
void TForm1::UpdateActionProgress(unsigned progress){
static unsigned numPasses = 0;
const unsigned passWidth = frmProgressDlg->pbTotalProcessing->Max/numToProcess;
unsigned prevPos = frmProgressDlg->pbProcessing->Position;
int delta = progress-prevPos;
if(delta<0) {
delta=5;
numPasses++;
frmProgressDlg->pbTotalProcessing->Position = numPasses*passWidth;
}
frmProgressDlg->pbProcessing->Position = progress;
frmProgressDlg->pbTotalProcessing->Position += (delta/numToProcess);
if(progress>=100 && numToProcess==(numPasses+1))
frmProgressDlg->pbTotalProcessing->Position = 100;
//close the dialogue when finished
if(frmProgressDlg->pbTotalProcessing->Position>=100) {
frmProgressDlg->Close();
frmProgressDlg->pbTotalProcessing->Position = 0;
numPasses = 0;
}
}else{ //or show the dialogue if not already shown
if(!(frmProgressDlg->Visible))frmProgressDlg->Show();
}
UPDATE: Like I said in a comment, I'm not updating the GUI from the worker thread.
Basically, the method UpdateActionProgress
is always called from the main thread in a while
loop (in UpdateProgressFromThread
).
So, the code calling UpdateActionProgress
is like this:
void TForm1::DrawFilteredWave(EFilterType eFilterType, EWindow eWnd,
unsigned cutoffFreqLo, unsigned cutoffFreqHi, unsigned filterLength,
vector<PFILTERBAND_INFO> &vBandInfo, bool invert ){
....
pDigitalFilter->UseBackgroundThread(true);
pDigitalFilter->ApplyFilter(pSelData, numSamples);
//if using a background thread, wait till it has finished executing
UpdateProgressFromThread(pDigitalFilter);
....
}
void TForm1::UpdateProgressFromThread(void *pp){
DigitalFilter *p = (DigitalFilter*)pp;
if(p->IsBackgroundThread()) {
while(!(p->IsBackgroundThreadFinished())) {
unsigned progress = p->GetProgressValue();
if(progress>0) {
UpdateActionProgress(progress);
}
}
}
}
Still, I'm updating the GUI using an asynchronous queue (a very simple queue) and I'm not using using TThread::Synchronize
because it's broken (see this). I tried using Synchronize
but the app would hang on a call to Synchronize
.
I will try to reproduce this using the least amount of code possible, but at the moment, this is all I have.
c++ vcl c++builder-6
|
show 6 more comments
I have a simple dialogue, which contains two TProgressBar
controls and two TStaticText
controls. The dialogue looks like this:
When I start painting the two progress bars, the two static text controls disappear (and reappear after the painting has finished).
The code doing the painting (probably irrelevant but here it is all the same)
void TForm1::UpdateActionProgress(unsigned progress){
static unsigned numPasses = 0;
const unsigned passWidth = frmProgressDlg->pbTotalProcessing->Max/numToProcess;
unsigned prevPos = frmProgressDlg->pbProcessing->Position;
int delta = progress-prevPos;
if(delta<0) {
delta=5;
numPasses++;
frmProgressDlg->pbTotalProcessing->Position = numPasses*passWidth;
}
frmProgressDlg->pbProcessing->Position = progress;
frmProgressDlg->pbTotalProcessing->Position += (delta/numToProcess);
if(progress>=100 && numToProcess==(numPasses+1))
frmProgressDlg->pbTotalProcessing->Position = 100;
//close the dialogue when finished
if(frmProgressDlg->pbTotalProcessing->Position>=100) {
frmProgressDlg->Close();
frmProgressDlg->pbTotalProcessing->Position = 0;
numPasses = 0;
}
}else{ //or show the dialogue if not already shown
if(!(frmProgressDlg->Visible))frmProgressDlg->Show();
}
UPDATE: Like I said in a comment, I'm not updating the GUI from the worker thread.
Basically, the method UpdateActionProgress
is always called from the main thread in a while
loop (in UpdateProgressFromThread
).
So, the code calling UpdateActionProgress
is like this:
void TForm1::DrawFilteredWave(EFilterType eFilterType, EWindow eWnd,
unsigned cutoffFreqLo, unsigned cutoffFreqHi, unsigned filterLength,
vector<PFILTERBAND_INFO> &vBandInfo, bool invert ){
....
pDigitalFilter->UseBackgroundThread(true);
pDigitalFilter->ApplyFilter(pSelData, numSamples);
//if using a background thread, wait till it has finished executing
UpdateProgressFromThread(pDigitalFilter);
....
}
void TForm1::UpdateProgressFromThread(void *pp){
DigitalFilter *p = (DigitalFilter*)pp;
if(p->IsBackgroundThread()) {
while(!(p->IsBackgroundThreadFinished())) {
unsigned progress = p->GetProgressValue();
if(progress>0) {
UpdateActionProgress(progress);
}
}
}
}
Still, I'm updating the GUI using an asynchronous queue (a very simple queue) and I'm not using using TThread::Synchronize
because it's broken (see this). I tried using Synchronize
but the app would hang on a call to Synchronize
.
I will try to reproduce this using the least amount of code possible, but at the moment, this is all I have.
c++ vcl c++builder-6
Please provide a Minimal, Complete, and Verifiable example demonstrating the problem in action. Where isUpdateActionProgress()
being called from? What you describe sounds like it is being called in a loop that blocks the main message loop from processing new UI messages until the loop ends.
– Remy Lebeau
Nov 22 at 22:20
@Remy Lebeau, the whole code is quite lengthy and I'm currently using threads and updating from a worker thread. Still, this didn't work even when I used only a single thread (the main thread). That's why I didn't post the whole thing. I assumed that someone had a similar problem. I can post the whole thing but it's going to take a while.
– dsp_user
Nov 22 at 22:36
Again, please provide a Minimal, Complete, and Verifiable example (emphasis on Minimal). And I hope you are not callingUpdateActionProgress()
directly in your worker threads. The VCL is not thread-safe, UI updates must to be synchronized with the main UI thread. Drawing issues are the least of your worries if you don't do that properly.
– Remy Lebeau
Nov 22 at 22:42
I've updated my answer, for now.
– dsp_user
Nov 22 at 23:03
1
That while() loop in UpdateProgressFromThread() is fatal, it prevents the UI thread from dispatching anything else. Like the WM_PAINT notifications of those static controls. You'll have to rethink this, maybe a timer.
– Hans Passant
Nov 23 at 0:17
|
show 6 more comments
I have a simple dialogue, which contains two TProgressBar
controls and two TStaticText
controls. The dialogue looks like this:
When I start painting the two progress bars, the two static text controls disappear (and reappear after the painting has finished).
The code doing the painting (probably irrelevant but here it is all the same)
void TForm1::UpdateActionProgress(unsigned progress){
static unsigned numPasses = 0;
const unsigned passWidth = frmProgressDlg->pbTotalProcessing->Max/numToProcess;
unsigned prevPos = frmProgressDlg->pbProcessing->Position;
int delta = progress-prevPos;
if(delta<0) {
delta=5;
numPasses++;
frmProgressDlg->pbTotalProcessing->Position = numPasses*passWidth;
}
frmProgressDlg->pbProcessing->Position = progress;
frmProgressDlg->pbTotalProcessing->Position += (delta/numToProcess);
if(progress>=100 && numToProcess==(numPasses+1))
frmProgressDlg->pbTotalProcessing->Position = 100;
//close the dialogue when finished
if(frmProgressDlg->pbTotalProcessing->Position>=100) {
frmProgressDlg->Close();
frmProgressDlg->pbTotalProcessing->Position = 0;
numPasses = 0;
}
}else{ //or show the dialogue if not already shown
if(!(frmProgressDlg->Visible))frmProgressDlg->Show();
}
UPDATE: Like I said in a comment, I'm not updating the GUI from the worker thread.
Basically, the method UpdateActionProgress
is always called from the main thread in a while
loop (in UpdateProgressFromThread
).
So, the code calling UpdateActionProgress
is like this:
void TForm1::DrawFilteredWave(EFilterType eFilterType, EWindow eWnd,
unsigned cutoffFreqLo, unsigned cutoffFreqHi, unsigned filterLength,
vector<PFILTERBAND_INFO> &vBandInfo, bool invert ){
....
pDigitalFilter->UseBackgroundThread(true);
pDigitalFilter->ApplyFilter(pSelData, numSamples);
//if using a background thread, wait till it has finished executing
UpdateProgressFromThread(pDigitalFilter);
....
}
void TForm1::UpdateProgressFromThread(void *pp){
DigitalFilter *p = (DigitalFilter*)pp;
if(p->IsBackgroundThread()) {
while(!(p->IsBackgroundThreadFinished())) {
unsigned progress = p->GetProgressValue();
if(progress>0) {
UpdateActionProgress(progress);
}
}
}
}
Still, I'm updating the GUI using an asynchronous queue (a very simple queue) and I'm not using using TThread::Synchronize
because it's broken (see this). I tried using Synchronize
but the app would hang on a call to Synchronize
.
I will try to reproduce this using the least amount of code possible, but at the moment, this is all I have.
c++ vcl c++builder-6
I have a simple dialogue, which contains two TProgressBar
controls and two TStaticText
controls. The dialogue looks like this:
When I start painting the two progress bars, the two static text controls disappear (and reappear after the painting has finished).
The code doing the painting (probably irrelevant but here it is all the same)
void TForm1::UpdateActionProgress(unsigned progress){
static unsigned numPasses = 0;
const unsigned passWidth = frmProgressDlg->pbTotalProcessing->Max/numToProcess;
unsigned prevPos = frmProgressDlg->pbProcessing->Position;
int delta = progress-prevPos;
if(delta<0) {
delta=5;
numPasses++;
frmProgressDlg->pbTotalProcessing->Position = numPasses*passWidth;
}
frmProgressDlg->pbProcessing->Position = progress;
frmProgressDlg->pbTotalProcessing->Position += (delta/numToProcess);
if(progress>=100 && numToProcess==(numPasses+1))
frmProgressDlg->pbTotalProcessing->Position = 100;
//close the dialogue when finished
if(frmProgressDlg->pbTotalProcessing->Position>=100) {
frmProgressDlg->Close();
frmProgressDlg->pbTotalProcessing->Position = 0;
numPasses = 0;
}
}else{ //or show the dialogue if not already shown
if(!(frmProgressDlg->Visible))frmProgressDlg->Show();
}
UPDATE: Like I said in a comment, I'm not updating the GUI from the worker thread.
Basically, the method UpdateActionProgress
is always called from the main thread in a while
loop (in UpdateProgressFromThread
).
So, the code calling UpdateActionProgress
is like this:
void TForm1::DrawFilteredWave(EFilterType eFilterType, EWindow eWnd,
unsigned cutoffFreqLo, unsigned cutoffFreqHi, unsigned filterLength,
vector<PFILTERBAND_INFO> &vBandInfo, bool invert ){
....
pDigitalFilter->UseBackgroundThread(true);
pDigitalFilter->ApplyFilter(pSelData, numSamples);
//if using a background thread, wait till it has finished executing
UpdateProgressFromThread(pDigitalFilter);
....
}
void TForm1::UpdateProgressFromThread(void *pp){
DigitalFilter *p = (DigitalFilter*)pp;
if(p->IsBackgroundThread()) {
while(!(p->IsBackgroundThreadFinished())) {
unsigned progress = p->GetProgressValue();
if(progress>0) {
UpdateActionProgress(progress);
}
}
}
}
Still, I'm updating the GUI using an asynchronous queue (a very simple queue) and I'm not using using TThread::Synchronize
because it's broken (see this). I tried using Synchronize
but the app would hang on a call to Synchronize
.
I will try to reproduce this using the least amount of code possible, but at the moment, this is all I have.
c++ vcl c++builder-6
c++ vcl c++builder-6
edited Nov 23 at 23:23
Remy Lebeau
330k18251442
330k18251442
asked Nov 22 at 18:21
dsp_user
1,23521015
1,23521015
Please provide a Minimal, Complete, and Verifiable example demonstrating the problem in action. Where isUpdateActionProgress()
being called from? What you describe sounds like it is being called in a loop that blocks the main message loop from processing new UI messages until the loop ends.
– Remy Lebeau
Nov 22 at 22:20
@Remy Lebeau, the whole code is quite lengthy and I'm currently using threads and updating from a worker thread. Still, this didn't work even when I used only a single thread (the main thread). That's why I didn't post the whole thing. I assumed that someone had a similar problem. I can post the whole thing but it's going to take a while.
– dsp_user
Nov 22 at 22:36
Again, please provide a Minimal, Complete, and Verifiable example (emphasis on Minimal). And I hope you are not callingUpdateActionProgress()
directly in your worker threads. The VCL is not thread-safe, UI updates must to be synchronized with the main UI thread. Drawing issues are the least of your worries if you don't do that properly.
– Remy Lebeau
Nov 22 at 22:42
I've updated my answer, for now.
– dsp_user
Nov 22 at 23:03
1
That while() loop in UpdateProgressFromThread() is fatal, it prevents the UI thread from dispatching anything else. Like the WM_PAINT notifications of those static controls. You'll have to rethink this, maybe a timer.
– Hans Passant
Nov 23 at 0:17
|
show 6 more comments
Please provide a Minimal, Complete, and Verifiable example demonstrating the problem in action. Where isUpdateActionProgress()
being called from? What you describe sounds like it is being called in a loop that blocks the main message loop from processing new UI messages until the loop ends.
– Remy Lebeau
Nov 22 at 22:20
@Remy Lebeau, the whole code is quite lengthy and I'm currently using threads and updating from a worker thread. Still, this didn't work even when I used only a single thread (the main thread). That's why I didn't post the whole thing. I assumed that someone had a similar problem. I can post the whole thing but it's going to take a while.
– dsp_user
Nov 22 at 22:36
Again, please provide a Minimal, Complete, and Verifiable example (emphasis on Minimal). And I hope you are not callingUpdateActionProgress()
directly in your worker threads. The VCL is not thread-safe, UI updates must to be synchronized with the main UI thread. Drawing issues are the least of your worries if you don't do that properly.
– Remy Lebeau
Nov 22 at 22:42
I've updated my answer, for now.
– dsp_user
Nov 22 at 23:03
1
That while() loop in UpdateProgressFromThread() is fatal, it prevents the UI thread from dispatching anything else. Like the WM_PAINT notifications of those static controls. You'll have to rethink this, maybe a timer.
– Hans Passant
Nov 23 at 0:17
Please provide a Minimal, Complete, and Verifiable example demonstrating the problem in action. Where is
UpdateActionProgress()
being called from? What you describe sounds like it is being called in a loop that blocks the main message loop from processing new UI messages until the loop ends.– Remy Lebeau
Nov 22 at 22:20
Please provide a Minimal, Complete, and Verifiable example demonstrating the problem in action. Where is
UpdateActionProgress()
being called from? What you describe sounds like it is being called in a loop that blocks the main message loop from processing new UI messages until the loop ends.– Remy Lebeau
Nov 22 at 22:20
@Remy Lebeau, the whole code is quite lengthy and I'm currently using threads and updating from a worker thread. Still, this didn't work even when I used only a single thread (the main thread). That's why I didn't post the whole thing. I assumed that someone had a similar problem. I can post the whole thing but it's going to take a while.
– dsp_user
Nov 22 at 22:36
@Remy Lebeau, the whole code is quite lengthy and I'm currently using threads and updating from a worker thread. Still, this didn't work even when I used only a single thread (the main thread). That's why I didn't post the whole thing. I assumed that someone had a similar problem. I can post the whole thing but it's going to take a while.
– dsp_user
Nov 22 at 22:36
Again, please provide a Minimal, Complete, and Verifiable example (emphasis on Minimal). And I hope you are not calling
UpdateActionProgress()
directly in your worker threads. The VCL is not thread-safe, UI updates must to be synchronized with the main UI thread. Drawing issues are the least of your worries if you don't do that properly.– Remy Lebeau
Nov 22 at 22:42
Again, please provide a Minimal, Complete, and Verifiable example (emphasis on Minimal). And I hope you are not calling
UpdateActionProgress()
directly in your worker threads. The VCL is not thread-safe, UI updates must to be synchronized with the main UI thread. Drawing issues are the least of your worries if you don't do that properly.– Remy Lebeau
Nov 22 at 22:42
I've updated my answer, for now.
– dsp_user
Nov 22 at 23:03
I've updated my answer, for now.
– dsp_user
Nov 22 at 23:03
1
1
That while() loop in UpdateProgressFromThread() is fatal, it prevents the UI thread from dispatching anything else. Like the WM_PAINT notifications of those static controls. You'll have to rethink this, maybe a timer.
– Hans Passant
Nov 23 at 0:17
That while() loop in UpdateProgressFromThread() is fatal, it prevents the UI thread from dispatching anything else. Like the WM_PAINT notifications of those static controls. You'll have to rethink this, maybe a timer.
– Hans Passant
Nov 23 at 0:17
|
show 6 more comments
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436410%2fvcl-controls-disappearing-when-a-tprogressbar-is-being-painted%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436410%2fvcl-controls-disappearing-when-a-tprogressbar-is-being-painted%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Please provide a Minimal, Complete, and Verifiable example demonstrating the problem in action. Where is
UpdateActionProgress()
being called from? What you describe sounds like it is being called in a loop that blocks the main message loop from processing new UI messages until the loop ends.– Remy Lebeau
Nov 22 at 22:20
@Remy Lebeau, the whole code is quite lengthy and I'm currently using threads and updating from a worker thread. Still, this didn't work even when I used only a single thread (the main thread). That's why I didn't post the whole thing. I assumed that someone had a similar problem. I can post the whole thing but it's going to take a while.
– dsp_user
Nov 22 at 22:36
Again, please provide a Minimal, Complete, and Verifiable example (emphasis on Minimal). And I hope you are not calling
UpdateActionProgress()
directly in your worker threads. The VCL is not thread-safe, UI updates must to be synchronized with the main UI thread. Drawing issues are the least of your worries if you don't do that properly.– Remy Lebeau
Nov 22 at 22:42
I've updated my answer, for now.
– dsp_user
Nov 22 at 23:03
1
That while() loop in UpdateProgressFromThread() is fatal, it prevents the UI thread from dispatching anything else. Like the WM_PAINT notifications of those static controls. You'll have to rethink this, maybe a timer.
– Hans Passant
Nov 23 at 0:17