April 18, 2024, 01:14:42 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Dialog box question

Started by Rock Ridge Farm (Larry), October 10, 2006, 07:20:51 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Rock Ridge Farm (Larry)

I have a dialog box that I want to be able to update from anywhere in the program.
It contains one item - a text string.
How do I set the string from anywhere  while the dialog box is active and have it display?

Ionic Wind Support Team

If you are using ShowDialog then just use a global pointer to your dialog class.

Ionic Wind Support Team

Rock Ridge Farm (Larry)

Is there an example I can look at?

Ionic Wind Support Team

It is just a pointer that is defined globally that can be accessed anywhere.


MyDlg *gpDlg;

global sub main()
{
     MyDlg dlg;
     gpDlg = &MyDlg;
     dlg.Create....
     ...
     dlg.ShowDialog();
     App.Run();
     dlg.CloseDialog();
}

SomeClass::SomeFunction()
{
      if(gpDlg)
            gpDlg->UpdateText("Hello there");
}


Assuming of course you have an "UpdateText" method in your custom dialog class that updates the text of some control.

Ionic Wind Support Team

Ionic Wind Support Team

Works the same way in C++ too.  You have to run it under the debugger to see anything useful. 

What I was thinking of is forcing the debugger to start when you have a debug executable.  There really is no reason to execute it on its own like that.  Might solve the problem of programmers that forget to switch to a release build before selling their products, something I have encountered dozens of times in the past.

Ionic Wind Support Team

Rock Ridge Farm (Larry)

As usual I am still having trouble - I changed my dialog to be the same as your example.
Now it displays nothing - no Dialog box and no text.
I obviously need a complete working example.
I could not find anything in the examples directory.

Ionic Wind Support Team

My example was just pseudo code, just something to give you a direction to go on.  Keep plugging at it and you will get it.  If I write it for you you'll never learn anything ;)

So I will lead you to water, but it is up to you to drink.

Ionic Wind Support Team

Rock Ridge Farm (Larry)

I am still having a problem. I build a dialog with the tool and can not get it to do what I want.
I want to display an updatable field. With the field commented out the box displays.
With the field included the box does not display at all.

The following works and displays a dialog box.

SDia.Create(0,0,250,100,
AWS_POPUP|AWS_BORDER|AWS_DLGFRAME|AWS_SYSMENU|DS_MODALFRAME,
0,"Updating Portfolio - Please Wait",this);
SDia.AddControl(CTSTATIC,"Updating",15,12,52,20,
ABS_OWNERDRAW|AWS_CHILD|AWS_VISIBLE,
0x0,205);
/* SDia.AddControlEx("Test","Test",71,10,70,20,
ABS_OWNERDRAW|AWS_CHILD|AWS_VISIBLE,
0x200,206);
*/

The following does not:

SDia.Create(0,0,250,100,
AWS_POPUP|AWS_BORDER|AWS_DLGFRAME|AWS_SYSMENU|DS_MODALFRAME,
0,"Updating Portfolio - Please Wait",this);
SDia.AddControl(CTSTATIC,"Updating",15,12,52,20,
ABS_OWNERDRAW|AWS_CHILD|AWS_VISIBLE,
0x0,205);
SDia.AddControlEx("Test","Test",71,10,70,20,
ABS_OWNERDRAW|AWS_CHILD|AWS_VISIBLE,
0x200,206);

Rock Ridge Farm (Larry)

I just went back to the dialog tool - it has the same problem.
I saved the code and compiled it.
With the addcontrolex it also fails.
Is this a bug of am I doing something wrong.
Use the tool and create a text field and a custom field.
with the custom field it does not display.
It works in the test mode but if you save the code and compile it it fails.

LarryMc

QuoteSDia.AddControlEx("Test","Test",71,10,70,20,
      ABS_OWNERDRAW|AWS_CHILD|AWS_VISIBLE,
      0x200,206);
Doesn't that first "Test" have to be a valid windows class?

Just a guess.  Put "button" there and see what happens.
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Rock Ridge Farm (Larry)

October 12, 2006, 09:15:17 AM #10 Last Edit: October 12, 2006, 09:20:02 AM by Rock Ridge Farm (Larry)
That worked - strange - dialog editor just put "" in that field.
Now if can get the updatetext part to work.

Ionic Wind Support Team

You chose a custom control.  It is up to you to add the window class, which can be done from the dialog editor.  The custom control is meant for classes that are registered with windows but not available through the normal common controls. 

If all you wat is a text display then pick a static control and change it's flags to 0. 
Ionic Wind Support Team

Rock Ridge Farm (Larry)

I have this almost working.
When I do the Upd->UpdateText("new text");
It does not display unless i place a Upd->ShowDialog(); call after it.
Since this is inside a loop it really goes crazy.
Similar to the below.

Asubroutine() // displays nothing
{
     do {
       // code here//
       Upd->updatetext("some string");
     } until done;
}

Asubroutine() // displays but ends up in an endless loop
{
     do {
       // code here//
       Upd->updatetext("some string");
       Upd->ShowDialog();
     } until done;
}

J B Wood (Zumwalt)

You can't call showDialog again, if you do you will end up in a loop of open dialogs.
You need to somehow just redraw the current control, so a control.refresh of some sorts is needed or a repaint.

Rock Ridge Farm (Larry)

That is the part I am having problems with.

Ionic Wind Support Team

I would really need to see more of your code.  However if you're using ShowDialog then it is a non-modal dialag and probably behind something.

Upd->ShowWindow(SWSHOW);

After you update the text would bring the dialog back on top.

You also don't specify what control you are using.  And what the UpdateText method does.  A static control will automatically repaint itself if you have the correct style.  So will most other controls.
Ionic Wind Support Team

Rock Ridge Farm (Larry)

much too large to post - I will rip the problem code out and see if can make a stand alone version.
Will take me a bit.

J B Wood (Zumwalt)

Make it eaiser on yourself, simply start a new project, add a dialog control, then create the code automatically.
Finally try to mod it. Don't rip apart your current code.
That thing Paul wrote for the auto gen code is pure genious.

Rock Ridge Farm (Larry)

The following is a ripped up version with the same problem.
Compile as a windows prog.
Select 'Stock' menu then 'Portfolio Price Update'
Drag the message box out of the way and notice that the dialog did not update.


#define WS_VISIBLE 0x10000000 // Control is visible
import int EnableWindow(unsigned int hwnd,int bEnable);
import int LoadImage alias LoadImageA(int hInstance,string *lpszName,int uType,int cxDesired,int cydesired,int fuLoad);
import int DeleteObject(int obj);
import int GetObject alias GetObjectA(int hgdiobj, int cbBuffer, void *lpvObject);
import int BitBlt(int hdcDest,int nXDest,int nYDest,int nWidth,
int nHeight,int hdcSrc,int nXSrc,int nYSrc,int dwRop);
import int BringWindowToTop(unsigned int handle);

#define MN_QUIT 350
#define MN_NEW 351
#define MN_UPDATE 352
#define MN_DELETE 353

// Style constants not yet in system includes
const DS_MODALFRAME  = 0x0080;
const GCL_HCURSOR    = -12;
const IDC_ARROW      = 32512;
const IDC_HAND       = 0x7F89;
const SS_NOTIFY      = 0x0100;
const SS_CENTERIMAGE = 0x0200;
const SS_SUNKEN      = 0x1000;
const WM_LBUTTONDOWN = 32513;

// General dialog constants
//const IDCANCEL = 0;
const IDOK     = 1;

// TrackMouseEvent constants
const TME_HOVER = 1;
const TME_LEAVE = 2;
const WM_MOUSEHOVER = 0x2A1;
const WM_MOUSELEAVE = 0x2A3;
const FILE_EXIT   =  1;

const POSIT_MTC   =  11;
const POSIT_EDIT  =  12;
const POSIT_UPD   =  13;
const POSIT_LSTVW =  14;
const POSIT_UPDQT =  15;
const PRICE_LSTVW =  16;
const SECMS_UPDQT =  17;
const SECMS_LSTVW =  18;

const HELP_ABOUT  =  21;
const HELP_HELP   =  22;

// Field constants
const STATIC_1    = 100;
const STATIC_2    = 101;

const INP_SYM     = 200;
const INP_NAM     = 201;

struct BITMAP {
int   bmType;
int   bmWidth;
int   bmHeight;
int   bmWidthBytes;
int   bmPlanes;
int   bmBitsPixel;
void *bmBits;
}


class Stkkepr:CDialog {
//the class constructor
declare Stkkepr();
//virtual overrides
declare OnInitDialog(),int;
declare OnClose(),int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl),int;
declare OnMenuInit(unsigned int hMenu),int;
declare OnMenuPick(int nID),int;
declare OnTimer(int nIDEvent),int;
declare SetBitmap(string *path);

//methods
declare UpdateData(int bDirection);
declare CloseAll();
declare SetupControls();
declare DoUpdate();
declare DoNew();
declare DoDelete();
declare DoIdle();
declare InitSelect();
declare BldStkLst();
declare BldSmsLst();
declare BldPrcLst();
//member variables
//access to control classes

CButton *m_buttonNext,*m_buttonPrev,*m_buttonUpdate;
}

// class PupdDialog:Dialog
class PupdDialog:CDialog{
// Constructor/Destructor
declare  PupdDialog();
declare _PupdDialog();

// Overridden methods
declare OnClose(), int;
declare OnControl(int nID, int nNotifyCode, unsigned int hControl), int;
declare OnCreate(), int;
declare OnInitDialog(),int;
declare loadList(int listno, ClistView *plist),int;

// Class methods
declare Make(Cwindow *parent), void; // creates the dialog
declare SetTitle(string sTitle), void; // dialog title
declare SetCaption(string sCaption), void; // text under the image
declare SetText(string sText), void; // dialog main text

// Class variables
string pupd_stitle;
string m_sCaption;
string pupd_stext;
int    m_TextHeight; // for main dialog text


// Class constants
const QD_OK      = 1; // for OnControl() method "quick dialog OK"
const QD_CAPTION = 3;
const QD_TEXT    = 4;
}

PupdDialog::PupdDialog(){
return;
}

PupdDialog::_PupdDialog(){
return;
}

PupdDialog::Make(Cwindow *parent), void{
Create(0,0,200,100,
AWS_POPUP|AWS_BORDER|AWS_DLGFRAME|AWS_SYSMENU,
0,pupd_stitle,parent);

AddControl(CTSTATIC,"",10,60,200,20,
AWS_CHILD|AWS_VISIBLE|SS_NOTIFY|ASS_MULTILINE,0x0,
QD_CAPTION);

AddControl(CTSTATIC,"",20,30,50,20,
AWS_CHILD|AWS_VISIBLE|ASS_MULTILINE|SS_NOTIFY,0x0,
QD_TEXT);

return;
}

PupdDialog::OnControl(int nID, int nNotifyCode, unsigned int hControl), int{
select nID {
case QD_OK:
if(nNotifyCode = 0){
CloseDialog(IDOK);
return true;
}
}
return true;
}

PupdDialog::OnClose(), int{
CloseDialog(IDCANCEL);
return true;
}

PupdDialog::OnCreate(), int{
return true;
}

PupdDialog::OnInitDialog(),int{
CStatic *pControl;

pControl = GetControl(QD_CAPTION);
pControl ->SetText(m_sCaption);

pControl = GetControl(QD_TEXT);
pControl ->SetText(pupd_stext);

CenterWindow();
return true;
}

PupdDialog::SetTitle(string sTitle), void{
pupd_stitle = sTitle;
return;
}

PupdDialog::SetCaption(string sCaption), void{
// this is the caption under the image, not the caption for the window itself
// one or two brief lines of text with "\n"
m_sCaption = sCaption;
return;
}

PupdDialog::SetText(string sText), void{
// lines separated by "\n"
pupd_stext = sText;
return;
}

// class SKWindow:window
class SKWindow:Cwindow{
// overridden methods
declare OnClose(),  int;
declare OnCreate(), int;
declare OnMenuPick(int nID), int;
declare SetBitmap(string *path);

// new methods
declare WriteCenteredText(int x1, int x2, int y, string s);
// class variables
def m_run as int;
CStatusBar *m_pStatus;
pointer m_pChild;
Stkkepr mainwin;

}

SKWindow::OnClose(), int{
m_run = 0;
Destroy();
return True;
}

SKWindow::OnCreate(), int{
m_run = 1;
CenterWindow();
mainwin.Create(0,0,600,400,
AWS_VISIBLE|AWS_OVERLAPPEDWINDOW|AWS_AUTODRAW,0,"Portfolio Management System",this);

return true;
}

SKWindow::OnMenuInit(), int{
return true;
}

PupdDialog *Pupd;

SKWindow::OnMenuPick(int nID), int{

PupdDialog *d2;

select (nID) {
case FILE_EXIT:
m_run = 0;
case HELP_ABOUT:
mainwin.ShowDialog();
case POSIT_UPDQT:
d2 = new(PupdDialog,1);
d2->SetTitle("Updating Portfolio Prices");
d2->SetCaption("A Rock Ridge Farm Product");
d2->SetText("Testing\n");
d2->Make(this);
Pupd = d2;
d2->ShowDialog();
updportfolio();
delete d2;

default:
}
return True;
}

SKWindow::WriteCenteredText(int x1, int x2, int y, string s),void{
// x1 is the leftmost limit, x2 the rightmost; y the distance from top
int offset;
point myPoint;

myPoint = GetTextSize(s); // width of string
offset = (x2 - x1 - myPoint.x) / 2; // offset from x1
WriteText(x1 + offset, y, s);
return;
}

SKWindow :: SetBitmap(string *path){
BITMAP bm;
DeleteObject(m_hBitmap);
m_hBitmap = LoadImage(0, path, 0,0,0,16);
GetObject(m_hBitmap, len(BITMAP), bm);
int dc = GetHDC();
BitBlt(dc, 0,0,bm.bmWidth,bm.bmHeight,dc,0,0,0x00CC0020);
ReleaseHDC(dc, true);
return;
}

// *****************************************************************************
// *                              MAIN SUBROUTINE                              *
// *****************************************************************************


global sub main(){
def SKWin as SKWindow;
int nReturn;
Cstatic Stat;
Cmenu m; // Unused or unready menu items are grayed

m.BeginMenu();


m.MenuTitle("&File");
m.MenuItem("E&xit",         AMF_ENABLED, FILE_EXIT);
m.MenuTitle("&Stock");
m.MenuItem("&Maintenance",  AMF_ENABLED, POSIT_MTC);
m.MenuItem("&View Portfolio",     AMF_ENABLED, POSIT_LSTVW);
m.MenuItem("&Portfolio Price Update", AMF_ENABLED, POSIT_UPDQT);
m.MenuItem("&View Sec Mast Update", AMF_ENABLED, SECMS_LSTVW);
m.MenuItem("&Master Price Update", AMF_ENABLED, SECMS_UPDQT);
m.MenuTitle("&Help");
m.MenuItem("&About...",     AMF_ENABLED, HELP_ABOUT);
m.Separator();
m.MenuItem("&Help",         AMF_GRAYED,  HELP_HELP);
m.EndMenu();

SKWin.Create(320,240,700,600,
AWS_VISIBLE|AWS_OVERLAPPEDWINDOW|AWS_AUTODRAW,0,"Rock Ridge Farm Portfolio Management System",null);
SKWin.SetWindowColor(0); // image background is black
SKWin.SetBitmap(".\\rrfarm.bmp");
SKWin.DrawMode(TRANSPARENT);//text
SKWin.FrontPen(0xfff000);//text
SKWin.SetFont("Courier Italic", 20,100);//text
SKWin.WriteText(40,300, "       Rock Ridge Farm");//text
SKWin.WriteText(10,330, "Portfolio Management System");//text
SKWin.SetMenu(m.Detach());
SKWin.DrawMode(TRANSPARENT);

// message loop
do {
wait();
} until SKWin.m_run = 0;
return;
}


Stkkepr::Stkkepr(){
}

Stkkepr::OnClose(),int{
CloseAll();
return true;
}

Stkkepr::OnInitDialog(),int {

//add the menu
Cmenu m;
m.BeginMenu();
m.MenuTitle( "&File");
m.MenuItem( "&Quit",0,MN_QUIT);
m.MenuTitle( "&Edit");
m.MenuItem( "&Update",0,MN_UPDATE);
m.MenuItem( "&New",0,MN_NEW);
m.MenuItem( "&Delete",0,MN_DELETE);
m.EndMenu();
SetMenu(m.Detach());

/* Initialize any controls here */

//start the idle time
StartTimer(1000);
return true;
}

Stkkepr::OnTimer(int nIDEvent),int{
DoIdle();
return True;
}

Stkkepr::OnControl(int nID, int nNotifyCode, unsigned int hControl),int{

return true;
}

Stkkepr::OnMenuPick(int nID),int{
select(nID){
case MN_QUIT:

CloseAll();
case MN_DELETE:

EnableWindow(m_buttonNext->m_hWnd,1);
case MN_NEW:

case MN_UPDATE:

}
return true;
}

Stkkepr::OnMenuInit(unsigned int hMenu),int{
Cmenu m;
m.Attach(hMenu);

m.Detach();
return true;
}

Stkkepr::UpdateData(int bDirection),int{

return(0);
}

Stkkepr::CloseAll() {
StopTimer();
CloseDialog(0);
}

Stkkepr::SetupControls() {

EnableWindow(m_buttonUpdate->m_hWnd,0);

}

Stkkepr::DoNew() {

return;
}

Stkkepr::DoUpdate() {

}

Stkkepr::DoDelete() {

return;
}

Stkkepr::DoIdle() {
STRING strCaption = GetCaption();
INT pos = StrFind(strCaption,"*");

}

Stkkepr::InitSelect() {
// Set counter to first record
curcount = 1;
}

sub updportfolio(){
string sel,error,dissym;
dstring cur_symbol[10],cur_tick[5],cur_name[40];
dstring prc_symbol[10],prc_date[18];
double cur_lstprc = 0;
double prc_lstprc = 0;
int cur_id,prc_id,nReturn,sptr,eptr,cnt,prccnt,curprcidx;
int stkstmt_select,stkstmt_update,stkstmt_insert,stkstmt_delete;
int prcstmt_select,prcstmt_update,prcstmt_insert,prcstmt_delete;

cur_id = 1;
do{
Pupd->SetText("Updating: " + numtostr(cur_id));
Pupd->ShowWindow(SWSHOW);
cur_id = cur_id + 1;
} UNTIL cur_id = 10000;

messagebox(0,"test","test");
return;
}

Ionic Wind Support Team

Pupd = d2;
d2->ShowDialog();
updportfolio();
delete d2;

Deleting the dialog here is a no no.  Even though you're assigning the pointer it is just that, a pointer.  Once you delete the dialog is is invalidate and the global pointer then contains the address of an invalid dialog.  You should only delete it when the program exits if you expect to be able to use that dialog through the length of the program.

That's the first problem.  The second is you're creating the dialog every time you have a menu pick of POSIT_UPDQT. 

Create and initialize the dialog in the main function, remove the AWS_VISIBLE stlye from the Create call so the dialog is shown as initially hidden.  Then when you receive the POSIT_UPDQT menu pick use Pupd->ShowWindow(SWSHOW).   When the close button is pressed in that dialog don't call CloseDialog but instead call ShowWindow(SWHIDE).

Thats from a brief look.  I am sure there are other problems to be found.

Keep in mind that a pointer is just the address of an object (whether that object be a class, variable, function, whatever) located somewhere else. And if you delete the object then that address is useless since it now points to invalid data.  Doesn't matter where you delete it from.

Ionic Wind Support Team

Rock Ridge Farm (Larry)

October 13, 2006, 12:59:43 PM #20 Last Edit: October 13, 2006, 01:01:27 PM by Rock Ridge Farm (Larry)
I created the dialog, called a function - used it, then deleted it.
The dialog is local to the button selected. An event of the button selection.
The pointer is assigned after each create and should therefore be valid.
While in the function the dialog should exist and should be updatable - it does not update the screen
in the function. Are you telling me that they are separate and independent?
It would seem to be more effecient to create and delete within a specified section of code rather than
creating it and keeping it open for the life of the code.
This would be a valid flow in regular C - is C++/Aurora that different?

Parker

When you delete it there is no dialog anymore. It is dead. You only want to delete it when you are done with it forever. All languages function in the same way, except that some of them hide it from you through garbage collection. If you were writing a program using the API in C, you wouldn't call CloseDialog right after opening it. That's the same as deleting it - the dialog no longer exists.

Rock Ridge Farm (Larry)

October 13, 2006, 01:32:40 PM #22 Last Edit: October 13, 2006, 01:36:45 PM by Rock Ridge Farm (Larry)
I am done with it - it should be created on the menu item selection - used - then deleted.
If the menu item is selected again it should re-create, use, and delete as needed.
Typical of event driven programming.



EVENT:
    Menu Item selected.
        Menu item processing.
            dialog created
            subroutine called
            dialog  deleted

During the execution of the subroutine the event is still active and should reflect updates
from the subroutine.



J B Wood (Zumwalt)

I get what he is doing. Just remove the delete yourself in his code and then execute it to see what the scope of that dialog is.
Its life is limited and there is no reason to show/hide it constantly to take up memory.
How about on create you dynamicaly just set the title in its definition instead of trying to change it?

Ionic Wind Support Team

October 13, 2006, 08:45:45 PM #24 Last Edit: October 13, 2006, 08:47:40 PM by Paul Turley
I see now.  And see the solution.  When you update a control it must process messages to reflect any changes.  Therefore this loop:


do{
Pupd->SetText("Updating: " + numtostr(cur_id));
Pupd->ShowWindow(SWSHOW);
cur_id = cur_id + 1;
} UNTIL cur_id = 10000;



Won't do anything for you since it is all done during a single message, OnMenuPick.  Since no other messages are being processed in this "busy" loop then you don't see any changes.

This would be more correct:

Pupd->ShowWindow(SWSHOW);
do{
      Pupd->SetText("Updating: " + numtostr(cur_id));
      wait(1);
      cur_id = cur_id + 1;
} UNTIL cur_id = 10000;


WAIT(1); allows messages to contune processing while in busy loops. Then you would have to change your SetText method since all you are doing there is setting a string. 


PupdDialog::SetText(string sText), void{
// lines separated by "\n"
    pupd_stext = sText;
    CStatic *pControl = GetControl(QD_TEXT);
    pControl ->SetText(pupd_stext);
return;
}


I was hoping you would have figured it out on your own.
Ionic Wind Support Team