Home > Archive > SQL Anywhere database replication > January 2006 > DBTools ?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author DBTools ?
TPS

2005-12-24, 3:23 am

Is it possible to bring up the standard Sybase SQL Remote dialog window with
the progress bar only through the DBTools interface? If it is can it also
automatically shutdown when replication is complete?

Version 8.02.4258

Thanks
TPS



TPS

2005-12-26, 3:28 am

When I create my own progress bar I am having an issue with the return value
of the callback that indicates %complete counting up by 100 in an infinite
loop whenever I send a message to the progress bar.

i.e. instead of V1 returning 0,0,1,3,5,15,23,etc

I get 100,200,300,400,500....to infinity.

If I take the sendmessage out an watch V1 in the debugger it behaves
normally.

An ideas???

Thanks
TPS




"TPS" <ts@scientexlc.com> wrote in message news:43acff9f@forums
-2-dub...
> Is it possible to bring up the standard Sybase SQL Remote dialog window
> with the progress bar only through the DBTools interface? If it is can it
> also automatically shutdown when replication is complete?
>
> Version 8.02.4258
>
> Thanks
> TPS
>
>
>



Rob Waywell

2005-12-27, 11:23 am

Did you want to show the code snippet that is giving you trouble?

--
-----------------------------------------------
Robert Waywell
Sybase Adaptive Server Anywhere Developer - Version 8
Sybase Certified Professional

Sybase's iAnywhere Solutions

Please respond ONLY to newsgroup

EBF's and Patches: http://downloads.sybase.com
choose SQL Anywhere Studio >> change 'time frame' to all

To Submit Bug Reports:
http://case-express.sybase.com/cx/c...sc?CASETYPE=Bug

SQL Anywhere Studio Supported Platforms and Support Status
http://my.sybase.com/detail?id=1002288

"TPS" <ts@scientexlc.com> wrote in message news:43af690c$1@foru
ms-1-dub...
> When I create my own progress bar I am having an issue with the return
> value of the callback that indicates %complete counting up by 100 in an
> infinite loop whenever I send a message to the progress bar.
>
> i.e. instead of V1 returning 0,0,1,3,5,15,23,etc
>
> I get 100,200,300,400,500....to infinity.
>
> If I take the sendmessage out an watch V1 in the debugger it behaves
> normally.
>
> An ideas???
>
> Thanks
> TPS
>
>
>
>
> "TPS" <ts@scientexlc.com> wrote in message news:43acff9f@forums
-2-dub...
>
>



tps

2005-12-30, 1:23 pm

extern short _callback ProgIndexCallBack( a_sql_uint32 v1, a_sql_uint32 v2 )
{
ReplicateDlg::Test(v
1,v2);
return 0;
}

then inside test I call

void XX::Test(int v1, int v2)
{

m_Progress.SendDlgItemMessage function with the appropriate info.
}

However when this call occurs it is setting v1 to increments of 100 in an
infinite loop.
Take this call out and trace in the debugger v1 increments up to 100 has
expected and works fine.

TPS



"Rob Waywell" < rwaywell_no_spam_ple
ase@ianywhere.com> wrote in message
news:43b16f7f$1@foru
ms-1-dub...
> Did you want to show the code snippet that is giving you trouble?
>
> --
> -----------------------------------------------
> Robert Waywell
> Sybase Adaptive Server Anywhere Developer - Version 8
> Sybase Certified Professional
>
> Sybase's iAnywhere Solutions
>
> Please respond ONLY to newsgroup
>
> EBF's and Patches: http://downloads.sybase.com
> choose SQL Anywhere Studio >> change 'time frame' to all
>
> To Submit Bug Reports:
> http://case-express.sybase.com/cx/c...sc?CASETYPE=Bug
>
> SQL Anywhere Studio Supported Platforms and Support Status
> http://my.sybase.com/detail?id=1002288
>
> "TPS" <ts@scientexlc.com> wrote in message news:43af690c$1@foru
ms-1-dub...
>
>



Rob Waywell

2006-01-02, 9:23 am

Can you elaborate on this call?


From your description it sounds like the problem is somewhere in the
"appropriate info" since you are observing that v1 as returned by the
callback increments correctly up to 100. So at that point you are no longer
in the SQL Remote code but back into your own application code. Is it
possible that you are assigning v1 and v2 to the wrong parameters in your
call to the m_Progress.SendDlgItemMessage.

--
-----------------------------------------------
Robert Waywell
Sybase Adaptive Server Anywhere Developer - Version 8
Sybase Certified Professional

Sybase's iAnywhere Solutions

Please respond ONLY to newsgroup

EBF's and Patches: http://downloads.sybase.com
choose SQL Anywhere Studio >> change 'time frame' to all

To Submit Bug Reports:
http://case-express.sybase.com/cx/c...sc?CASETYPE=Bug

SQL Anywhere Studio Supported Platforms and Support Status
http://my.sybase.com/detail?id=1002288

"tps" <ts@scientexlc.com> wrote in message news:43b579fb$1@foru
ms-2-dub...[color=darkred]
> extern short _callback ProgIndexCallBack( a_sql_uint32 v1, a_sql_uint32
> v2 )
> {
> ReplicateDlg::Test(v
1,v2);
> return 0;
> }
>
> then inside test I call
>
> void XX::Test(int v1, int v2)
> {
>
> m_Progress.SendDlgItemMessage function with the appropriate info.
> }
>
> However when this call occurs it is setting v1 to increments of 100 in an
> infinite loop.
> Take this call out and trace in the debugger v1 increments up to 100 has
> expected and works fine.
>
> TPS
>
>
>
> "Rob Waywell" < rwaywell_no_spam_ple
ase@ianywhere.com> wrote in message
> news:43b16f7f$1@foru
ms-1-dub...
>
>



TPS

2006-01-02, 1:23 pm

This is all in a MFC dialog class. I have change the calls to go in the
callback only. I have the progress bar statically declared.

extern short _callback ProgIndexCallBack( a_sql_uint32 v1, a_sql_uint32 v2 )
{
m_Progress.SetPos(v1); //MFC wrapper that is basically the call below.
// SendMessage(m_Progre
ss.m_hWnd, PBM_SETPOS, v1, 0L);
return 0;
}

Everytime the SetPos or SendMessage is called (I have tried both of them)
the value of v1 start to increment in an infinite loop by increments of 100.
This will even occur if I mack the call m_Progress.SetPos(50);

====================
====================
====================
==============
// ReplicateDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Replication.h"
#include "ReplicateDlg.h"

#include <windows.h>
#include <string.h>
#include <winbase.h>
#include <wininet.h>

#include <iostream.h>


#include "ReplicateDlg.h"
#include "ProcessReplication.h"

#include "ftp_c.h"

#include "ping.h"

#define WM_STOPCLIP WM_USER+1
#define WM_PLAYCLIP WM_USER+2
#define WM_SHOWFIRSTFRAME WM_USER+3
#define WM_SHOWLASTFRAME WM_USER+4
#pragma pack(1)

typedef short ( __stdcall * dbtoolsInitType)( const struct a_dbtools_info
*);
typedef short ( __stdcall * dbtoolsRemoteType)( const struct a_remote_sql
*);

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

static CProgressCtrl m_Progress;

extern short _callback ProgIndexCallBack( a_sql_uint32 v1, a_sql_uint32 v2 )
{
m_Progress.SetPos(v1);

SendMessage(m_Progre
ss.m_hWnd, PBM_SETPOS, v1, 0L);

return 0;
}

====================
====================
====================
====================
=
header file
====================
====================
====================
====================
=
//{{AFX_INCLUDES()
#include "progressbar.h"
//}}AFX_INCLUDES
#if
!defined(AFX_REPLICA
TEDLG_H__BE6ED239_67
89_4173_BA2D_7A0554C
3E87C__INCLUDED_)
#define AFX_REPLICATEDLG_H__
BE6ED239_6789_4173_B
A2D_7A0554C3E87C__IN
CLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ReplicateDlg.h : header file
//
#include "afxinet.h"

#include "dbtools.h"
#include "dbrmt.h"
/////////////////////////////////////////////////////////////////////////////
// ReplicateDlg dialog



class ReplicateDlg : public CDialog
{
// Construction
public:
ReplicateDlg(CWnd* pParent = NULL); // standard constructor
// Construction
protected:
CInternetSession* m_pInetSession;
CFtpConnection* m_pFtpConnection;
CString strServerName;

a_remote_sql replicateStruct;
a_dbtools_info dbtinfo;

public:

HCURSOR LoadAniCursor(UINT nID);

int connectftp();
void disconnectftp();
int processreplication()
;
void replicate();



// Dialog Data
//{& #123;AFX_DATA(Replic
ateDlg)
enum { IDD = IDD_DIALOG1 };

//}}AFX_DATA


// Overrides
// ClassWizard generated virtual function overrides
//{& #123;AFX_VIRTUAL(Rep
licateDlg)
protected:
virtual void DoDataExchange(CData
Exchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:

// Generated message map functions
//{& #123;AFX_MSG(Replica
teDlg)
virtual void OnOK();
virtual BOOL OnInitDialog();
afx_msg void OnButton1();
//}}AFX_MSG
DECLARE_MESSAGE_MAP(
)
};

//{& #123;AFX_INSERT_LOCA
TION}}
// Microsoft Visual C++ will insert additional declarations immediately
before the previous line.

#endif //
!defined(AFX_REPLICA
TEDLG_H__BE6ED239_67
89_4173_BA2D_7A0554C
3E87C__INCLUDED_)
====================
====================
====================
====================
====

TPS...




"Rob Waywell" < rwaywell_no_spam_ple
ase@ianywhere.com> wrote in message
news:43b93ecd$1@foru
ms-2-dub...
> Can you elaborate on this call?
>
>
> From your description it sounds like the problem is somewhere in the
> "appropriate info" since you are observing that v1 as returned by the
> callback increments correctly up to 100. So at that point you are no
> longer in the SQL Remote code but back into your own application code. Is
> it possible that you are assigning v1 and v2 to the wrong parameters in
> your call to the m_Progress.SendDlgItemMessage.
>
> --
> -----------------------------------------------
> Robert Waywell
> Sybase Adaptive Server Anywhere Developer - Version 8
> Sybase Certified Professional
>
> Sybase's iAnywhere Solutions
>
> Please respond ONLY to newsgroup
>
> EBF's and Patches: http://downloads.sybase.com
> choose SQL Anywhere Studio >> change 'time frame' to all
>
> To Submit Bug Reports:
> http://case-express.sybase.com/cx/c...sc?CASETYPE=Bug
>
> SQL Anywhere Studio Supported Platforms and Support Status
> http://my.sybase.com/detail?id=1002288
>
> "tps" <ts@scientexlc.com> wrote in message news:43b579fb$1@foru
ms-2-dub...
>
>



Volker Barth

2006-01-03, 3:23 am

Hi TPS,

I get the impression that this is more of a MFC/Windows
messaging item than a DBTools thing...
As I have developped an application that does just what you
want - namely have an MFC dialog displaying DBRemoteSQL's
progress - I can assure that this should work.

Just a few questions and hints:
1. What is displayed in the debugger window if you add
something like
TRACE("Progress: %ld / %ld\n", v1, v2);
in your callback?
2. I can't see how your dialog is called inside your app.
AFAIK it must be created as an modeless dialog.
3. Is your app multithreaded? Is the work of the DBTools API
separated from the GUI, for example through means of a
worker thread? - Otherwise, I could imagine that the work of
the DBTools API and the message handling in your app may
block each other. Furthermore, the message maps of MFC
controls can't be shared between threads (although then the
direct call of SendMessage with the control's handle should
work).
4. Is the range of the progress control set accordingly
(i.e. what does GetRange() return?

Maybe you could work out the flow of control inside your app
(especially the way the dialog and your calls of the DBTools
API work together).

HTH

Volker


> This is all in a MFC dialog class. I have change the calls
> to go in the callback only. I have the progress bar
> statically declared.
>
> extern short _callback ProgIndexCallBack( a_sql_uint32 v1,
> a_sql_uint32 v2 ) {
> m_Progress.SetPos(v1); //MFC wrapper that is
> basically the call below.
> // SendMessage(m_Progre
ss.m_hWnd, PBM_SETPOS, v1, 0L);
> return 0;
> }
>
> Everytime the SetPos or SendMessage is called (I have
> tried both of them) the value of v1 start to increment in
> an infinite loop by increments of 100. This will even
> occur if I mack the call m_Progress.SetPos(50);
>
> ====================
====================
==================
> ================ // ReplicateDlg.cpp : implementation file
> //
>
> #include "stdafx.h"
> #include "Replication.h"
> #include "ReplicateDlg.h"
>
> #include <windows.h>
> #include <string.h>
> #include <winbase.h>
> #include <wininet.h>
>
> #include <iostream.h>
>
>
> #include "ReplicateDlg.h"
> #include "ProcessReplication.h"
>
> #include "ftp_c.h"
>
> #include "ping.h"
>
> #define WM_STOPCLIP WM_USER+1
> #define WM_PLAYCLIP WM_USER+2
> #define WM_SHOWFIRSTFRAME WM_USER+3
> #define WM_SHOWLASTFRAME WM_USER+4
> #pragma pack(1)
>
> typedef short ( __stdcall * dbtoolsInitType)( const struct
> a_dbtools_info *);
> typedef short ( __stdcall * dbtoolsRemoteType)( const
> struct a_remote_sql *);
>
> #ifdef _DEBUG
> #define new DEBUG_NEW
> #undef THIS_FILE
> static char THIS_FILE[] = __FILE__;
> #endif
>
> static CProgressCtrl m_Progress;
>
> extern short _callback ProgIndexCallBack( a_sql_uint32 v1,
> a_sql_uint32 v2 ) {
> m_Progress.SetPos(v1);
>
> SendMessage(m_Progre
ss.m_hWnd, PBM_SETPOS, v1, 0L);
>
> return 0;
> }
>
> ====================
====================
==================
> ====================
=== header file
> ====================
====================
==================
> ====================
=== //{{AFX_INCLUDES()
> #include "progressbar.h"
> //}}AFX_INCLUDES
> #if
> !defined(AFX_REPLICA
TEDLG_H__BE6ED239_67
89_4173_BA2D_7A055
> 4C3E87C__INCLUDED_) #define
> AFX_REPLICATEDLG_H__
BE6ED239_6789_4173_B
A2D_7A0554C3E87C__
> INCLUDED_
>
> #if _MSC_VER > 1000
> #pragma once
> #endif // _MSC_VER > 1000
> // ReplicateDlg.h : header file
> //
> #include "afxinet.h"
>
> #include "dbtools.h"
> #include "dbrmt.h"
> //////////////////////////////////////////////////////////
> /////////////////// // ReplicateDlg dialog
>
>
>
> class ReplicateDlg : public CDialog
> {
> // Construction
> public:
> ReplicateDlg(CWnd* pParent = NULL); // standard
> constructor // Construction
> protected:
> CInternetSession* m_pInetSession;
> CFtpConnection* m_pFtpConnection;
> CString strServerName;
>
> a_remote_sql replicateStruct;
> a_dbtools_info dbtinfo;
>
> public:
>
> HCURSOR LoadAniCursor(UINT nID);
>
> int connectftp();
> void disconnectftp();
> int processreplication()
;
> void replicate();
>
>
>
> // Dialog Data
> //{& #123;AFX_DATA(Replic
ateDlg)
> enum { IDD = IDD_DIALOG1 };
>
> //}}AFX_DATA
>
>
> // Overrides
> // ClassWizard generated virtual function overrides
> //{& #123;AFX_VIRTUAL(Rep
licateDlg)
> protected:
> virtual void DoDataExchange(CData
Exchange* pDX); //
> DDX/DDV support
> //}}AFX_VIRTUAL
>
> // Implementation
> protected:
>
> // Generated message map functions
> //{& #123;AFX_MSG(Replica
teDlg)
> virtual void OnOK();
> virtual BOOL OnInitDialog();
> afx_msg void OnButton1();
> //}}AFX_MSG
> DECLARE_MESSAGE_MAP(
)
> };
>
> //{& #123;AFX_INSERT_LOCA
TION}}
> // Microsoft Visual C++ will insert additional
> declarations immediately before the previous line.
>
> #endif //
> !defined(AFX_REPLICA
TEDLG_H__BE6ED239_67
89_4173_BA2D_7A055
> 4C3E87C__INCLUDED_)
> ====================
====================
==================
> ====================
======
>
> TPS...
>
>
>
>
> "Rob Waywell" < rwaywell_no_spam_ple
ase@ianywhere.com>
> wrote in message news:43b93ecd$1@foru
ms-2-dub...
> appropriate info. >
> increments correctly up to 100. So at that point you are
> m_Progress.SendDlgItemMessage. >
>

http://case-express.sybase.com/cx/c...sc?CASETYPE=Bug[color=darkred]
> news:43b579fb$1@foru
ms-2-dub... >> extern short _callback
> ProgIndexCallBack( a_sql_uint32 v1, a_sql_uint32 >> v2 )
> appropriate info. >> }
> increments of 100 in an >> infinite loop.
> increments up to 100 has >> expected and works fine.
TPS

2006-01-03, 11:23 am

Volker..

Thanks for your reply.... Could you send me some sample code on how you
accomplished this.

My guess is that I do not have the the proper seperation between the dialog
and dbtools and I am hammering memory somewhere.
As soon as any call related to the dialog is made the value of v1 increments
by 100 and the callback goes into an infinite loop with
v1 icrementing by 100 for each call. (i.e.
100,200,300,400,500,
600,700,............)

Thanks

TPS




<Volker Barth> wrote in message news:43ba3ce7.70fb.1681692777@sybase.com...[color=darkred]
> Hi TPS,
>
> I get the impression that this is more of a MFC/Windows
> messaging item than a DBTools thing...
> As I have developped an application that does just what you
> want - namely have an MFC dialog displaying DBRemoteSQL's
> progress - I can assure that this should work.
>
> Just a few questions and hints:
> 1. What is displayed in the debugger window if you add
> something like
> TRACE("Progress: %ld / %ld\n", v1, v2);
> in your callback?
> 2. I can't see how your dialog is called inside your app.
> AFAIK it must be created as an modeless dialog.
> 3. Is your app multithreaded? Is the work of the DBTools API
> separated from the GUI, for example through means of a
> worker thread? - Otherwise, I could imagine that the work of
> the DBTools API and the message handling in your app may
> block each other. Furthermore, the message maps of MFC
> controls can't be shared between threads (although then the
> direct call of SendMessage with the control's handle should
> work).
> 4. Is the range of the progress control set accordingly
> (i.e. what does GetRange() return?
>
> Maybe you could work out the flow of control inside your app
> (especially the way the dialog and your calls of the DBTools
> API work together).
>
> HTH
>
> Volker
>
>
> http://case-express.sybase.com/cx/c...sc?CASETYPE=Bug


Volker Barth

2006-01-04, 7:23 am

Hi TPS,

I guess I can put together some excerpts from our
application later on.

But before that, I think you should clarify that the problem
is not in the DBRemoteSQL call itself.
I would suggest that you run your app in debug mode (but
without breaks and steps) and trace the parameter values via
a callback that just calls
TRACE("Progress: %ld / %ld\n", v1, v2);
or something like that. You should not send any message to
the progress control (or the dialog) in the callback then.
This should assure that your app gets the right parameter
values in the callback.
I would suggest that you don't use breaks and steps in this
test as stepping through might itself interfere with the
work of the DBRemoteSQL() call.
If this test runs as expected, I guess we can be sure that
the problem you face is connected to the GUI implementation.
If this test fails, maybe the calling conventions of the
callback are not set correctly (I stumbled over these things
quite often ;-) ).

The reason for my suggestion is the following:
Though there might be an invalid interconnection of message
handling and DBTools calls in your app, this doesn't explain
to me why the callback gets values like 100, 200 etc. for
v1.
If it would get those values for v2 (aka the value "max")
and v1 (aka "index") would remain on 0 or 1, I could imagine
that this could mean that DBRemoteSQL() changes its
expactation for the duration of the query upwards.

And a further test case:
What happens when you call something like
m_Progress.SetPos(50);
or
SendMessage(m_Progre
ss.m_hWnd, PBM_SETPOS, 50, 0L);
in your code just directly before or after you call
DBRemoteSQL()?
If this working as expected?
If not, this would indeed show that the interaction between
the code that runs DBRemoteSQL() and your GUI is not working
well. It would not be a any kind of callback stuff, either,
as the progress control would be called outside any
callback.

Just a few more hints...


Best regards
Volker

TPS wrote:
> Volker..
>
> Thanks for your reply.... Could you send me some sample
> code on how you accomplished this.
>
> My guess is that I do not have the the proper seperation
> between the dialog and dbtools and I am hammering memory
> somewhere. As soon as any call related to the dialog is
> made the value of v1 increments by 100 and the callback
> goes into an infinite loop with v1 icrementing by 100 for
> each call. (i.e. 100,200,300,400,500,
600,700
> ,............)
>
> Thanks
>
> TPS
>
>
>
>
> <Volker Barth> wrote in message
> work. >
> calls >> to go in the callback only. I have the progress
> bar >> statically declared.
> v1, >> a_sql_uint32 v2 ) {
> ; >> return 0;
> in >> an infinite loop by increments of 100. This will
> even >> occur if I mack the call m_Progress.SetPos(50);
> ====================
====================
==================
> file >> //
> struct >> a_dbtools_info *);
> v1, >> a_sql_uint32 v2 ) {
> ====================
====================
==================
> ====================
====================
==================
> "progressbar.h" >> //}}AFX_INCLUDES
> !defined(AFX_REPLICA
TEDLG_H__BE6ED239_67
89_4173_BA2D_7A055
> AFX_REPLICATEDLG_H__
BE6ED239_6789_4173_B
A2D_7A0554C3E87C__
> //////////////////////////////////////////////////////////
> !defined(AFX_REPLICA
TEDLG_H__BE6ED239_67
89_4173_BA2D_7A055
> ====================
====================
==================
> are >> > no longer in the SQL Remote code but back into
> your own >> > application code. Is it possible that you
> are assigning >> > v1 and v2 to the wrong parameters in
> your call to the >> m_Progress.SendDlgItemMessage. >
> all >> >
>

http://case-express.sybase.com/cx/c...sc?CASETYPE=Bug
> _callback >> ProgIndexCallBack( a_sql_uint32 v1,
> a_sql_uint32 >> v2 ) >> >> {
>
>

TPS

2006-01-04, 1:23 pm

Volker

My biggest problem is that I am not sure how to implement a worker thread
properly to get th v1 value to the progress control.

My replication is running correctly. My initial implementation I just showed
an animated gif indincating that the replication is processing. This works
great when the replication takes less than 20 seconds. However, on longer
replications the user is thinking the application is locking up. Thus my
idea of creating a progress bar.

I have created a mfc dll that 1st prompt the user if replication should
occur. I am doing this part in a model dialog. If the user replies yes than
I am creating a modeless dialog to display the progress bar. My problem is I
do not know how to get v1 to the progress bar now.

Should the callback routines be in the class supporting the modeless dialog
or in the class that creates the modeless dialog?

How does a worker thread communicate the static v1 to the progress bar??

Thanks for your help..

TPS


<Volker Barth> wrote in message news:43bb9729.5f01.1681692777@sybase.com...[color=darkred]
> Hi TPS,
>
> I guess I can put together some excerpts from our
> application later on.
>
> But before that, I think you should clarify that the problem
> is not in the DBRemoteSQL call itself.
> I would suggest that you run your app in debug mode (but
> without breaks and steps) and trace the parameter values via
> a callback that just calls
> TRACE("Progress: %ld / %ld\n", v1, v2);
> or something like that. You should not send any message to
> the progress control (or the dialog) in the callback then.
> This should assure that your app gets the right parameter
> values in the callback.
> I would suggest that you don't use breaks and steps in this
> test as stepping through might itself interfere with the
> work of the DBRemoteSQL() call.
> If this test runs as expected, I guess we can be sure that
> the problem you face is connected to the GUI implementation.
> If this test fails, maybe the calling conventions of the
> callback are not set correctly (I stumbled over these things
> quite often ;-) ).
>
> The reason for my suggestion is the following:
> Though there might be an invalid interconnection of message
> handling and DBTools calls in your app, this doesn't explain
> to me why the callback gets values like 100, 200 etc. for
> v1.
> If it would get those values for v2 (aka the value "max")
> and v1 (aka "index") would remain on 0 or 1, I could imagine
> that this could mean that DBRemoteSQL() changes its
> expactation for the duration of the query upwards.
>
> And a further test case:
> What happens when you call something like
> m_Progress.SetPos(50);
> or
> SendMessage(m_Progre
ss.m_hWnd, PBM_SETPOS, 50, 0L);
> in your code just directly before or after you call
> DBRemoteSQL()?
> If this working as expected?
> If not, this would indeed show that the interaction between
> the code that runs DBRemoteSQL() and your GUI is not working
> well. It would not be a any kind of callback stuff, either,
> as the progress control would be called outside any
> callback.
>
> Just a few more hints...
>
>
> Best regards
> Volker
>
> TPS wrote:
> http://case-express.sybase.com/cx/c...sc?CASETYPE=Bug


Volker Barth

2006-01-05, 11:23 am

Hi TPS,

as I told you yesterday I try to give some hints on our
implementation. I will not give much code samples because
some parts are coded in German language, and because there
would be too many irrelevant aspects for a sample. Instead I
will try to describe the main topics.

Preface: I don't think that is it the best way the wanted
result can be achieved - but at least it is working ;-)
And of course this is much more stuff on MFC than on ASA -
the newsgroup may forgive...


In contrast to what I told in my first post, we use a modal
dialog, not a modeless one. But we use a worker thread for
the DBTools calls, so the modal dialog stays "reactive"
while the replication takes place.

1. Our app is a dialog-based MFC app; as such it uses a
modal dialog.
This dialog has a bunch of controls, and one is the progress
bar - say m_prgStatus.

2. When the user clicks a "Start" button, the dialog box
creates a worker thread. This is implemented as a static
method of the dialog with the following signature:
static UINT DoTheWork(LPVOID lParam);
In MFC, this function must be a static method or global
function, cf. the MFC docs.
As the only parameter DoTheWork() gets the HWND of the
dialog.
So the OnStart()-handler looks something like:

void CMyDlg::OnOK()
{
CWinThread* pThread = AfxBeginThread(CMyDl
g::DoTheWork,
LPVOID(GetSafeHwnd()
));
ASSERT(pThread);
}

The use of a worker thread leads to the following situation:
The main thread is still handling the dialog's message loop,
e.g. the user can still interact with the dialog (and
possibly click on a "Abort" button).
In the meantime, the worker thread is doing his length work
in the background (and now and then checks the dialog's
abort state and comes to a clean end then).

3. The thread function does all the long work (by calls to
different "worker classes"), e.g. loading the db, connecting
to our comany's network, downloading the files for DBRemote
and the like.
One part is the call to DBRemoteSQL with the according
callbacks.
They are part of the corresponding worker class but do
nothing special (and like thread function, they must be
implemented as static methods or global functions).

E.g., the progress callback is something like:

(static) short
CReplManager::OnDbto
olProgressIndexCallb
ack(unsigned long
lCurIndex,
unsigned long lMaxIndex)
{
static unsigned long lMaxPart = 100;
if (lMaxIndex > 0)
{
lMaxPart = lMaxIndex;
NotifyProgress(0);
}
else
{
unsigned long lPercent = (lMaxPart > 0) ? ((lCurIndex *
100) / lMaxPart) : 0;
NotifyProgress(lPerc
ent);
}
return 0;
}

4. Internally, NotifyProgress() uses SendMessage to send a
user-defined message to the HWND of the dialog. As WPARAM,
the value of "lPercent" is given, which is the "normalized
value" of your "v1" parameter (e.g. with values between 0
and 100).
The dialog itself has an handler for this user-defined
message and looks something like:
m_prgStatus.SetPos(nPrgStatus);

5. As its last action, the worker thread function posts a
message to the dialog that it has finished.
::PostMessage(m_hDlg
, UM_WORK_FINISHED, bSuccess, 0L);
return nReturn;

6. The dialog has an according handler for this user-defined
message and displays its "I'm ready for more work" state.


So the DBTools calls are all done inside the worker thread,
whereas the UI is handled within the main thread.
One point is worth adding: In MFC, different threads can't
use the same message maps for CWnd-objects - therefore the
worker thread uses HWNDs instead if CWnd*.


TPS, I hope this might give you some advice.
I' m back on work on Monday, in case of further questions.

Best regards

Volker

TPS wrote:[color=darkred
]
> Volker
>
> My biggest problem is that I am not sure how to implement
> a worker thread properly to get th v1 value to the
> progress control.
>
> My replication is running correctly. My initial
> implementation I just showed an animated gif indincating
> that the replication is processing. This works great when
> the replication takes less than 20 seconds. However, on
> longer replications the user is thinking the application
> is locking up. Thus my idea of creating a progress bar.
>
> I have created a mfc dll that 1st prompt the user if
> replication should occur. I am doing this part in a model
> dialog. If the user replies yes than I am creating a
> modeless dialog to display the progress bar. My problem is
> I do not know how to get v1 to the progress bar now.
>
> Should the callback routines be in the class supporting
> the modeless dialog or in the class that creates the
> modeless dialog?
>
> How does a worker thread communicate the static v1 to the
> progress bar??
>
> Thanks for your help..
>
> TPS
>
>
> <Volker Barth> wrote in message
> upwards. >
Volker Barth

2006-01-05, 11:23 am

Hi TPS,

as I told you yesterday I try to give some hints on our
implementation. I will not give much code samples because
some parts are coded in German language, and because there
would be too many irrelevant aspects for a sample. Instead I
will try to describe the main topics.

Preface: I don't think that is it the best way the wanted
result can be achieved - but at least it is working ;-)
And of course this is much more stuff on MFC than on ASA -
the newsgroup may forgive...


In contrast to what I told in my first post, we use a modal
dialog, not a modeless one. But we use a worker thread for
the DBTools calls, so the modal dialog stays "reactive"
while the replication takes place.

1. Our app is a dialog-based MFC app; as such it uses a
modal dialog.
This dialog has a bunch of controls, and one is the progress
bar - say m_prgStatus.

2. When the user clicks a "Start" button, the dialog box
creates a worker thread. This is implemented as a static
method of the dialog with the following signature:
static UINT DoTheWork(LPVOID lParam);
In MFC, this function must be a static method or global
function, cf. the MFC docs.
As the only parameter DoTheWork() gets the HWND of the
dialog.
So the OnStart()-handler looks something like:

void CMyDlg::OnOK()
{
CWinThread* pThread = AfxBeginThread(CMyDl
g::DoTheWork,
LPVOID(GetSafeHwnd()
));
ASSERT(pThread);
}

The use of a worker thread leads to the following situation:
The main thread is still handling the dialog's message loop,
e.g. the user can still interact with the dialog (and
possibly click on a "Abort" button).
In the meantime, the worker thread is doing his length work
in the background (and now and then checks the dialog's
abort state and comes to a clean end then).

3. The thread function does all the long work (by calls to
different "worker classes"), e.g. loading the db, connecting
to our comany's network, downloading the files for DBRemote
and the like.
One part is the call to DBRemoteSQL with the according
callbacks.
They are part of the corresponding worker class but do
nothing special (and like thread function, they must be
implemented as static methods or global functions).

E.g., the progress callback is something like:

(static) short
CReplManager::OnDbto
olProgressIndexCallb
ack(unsigned long
lCurIndex,
unsigned long lMaxIndex)
{
static unsigned long lMaxPart = 100;
if (lMaxIndex > 0)
{
lMaxPart = lMaxIndex;
NotifyProgress(0);
}
else
{
unsigned long lPercent = (lMaxPart > 0) ? ((lCurIndex *
100) / lMaxPart) : 0;
NotifyProgress(lPerc
ent);
}
return 0;
}

4. Internally, NotifyProgress() uses SendMessage to send a
user-defined message to the HWND of the dialog. As WPARAM,
the value of "lPercent" is given, which is the "normalized
value" of your "v1" parameter (e.g. with values between 0
and 100).
The dialog itself has an handler for this user-defined
message and looks something like:
m_prgStatus.SetPos(nPrgStatus);

5. As its last action, the worker thread function posts a
message to the dialog that it has finished.
::PostMessage(m_hDlg
, UM_WORK_FINISHED, bSuccess, 0L);
return nReturn;

6. The dialog has an according handler for this user-defined
message and displays its "I'm ready for more work" state.


So the DBTools calls are all done inside the worker thread,
whereas the UI is handled within the main thread.
One point is worth adding: In MFC, different threads can't
use the same message maps for CWnd-objects - therefore the
worker thread uses HWNDs instead if CWnd*.


TPS, I hope this might give you some advice.
I' m back on work on Monday, in case of further questions.

Best regards

Volker

TPS wrote:[color=darkred
]
> Volker
>
> My biggest problem is that I am not sure how to implement
> a worker thread properly to get th v1 value to the
> progress control.
>
> My replication is running correctly. My initial
> implementation I just showed an animated gif indincating
> that the replication is processing. This works great when
> the replication takes less than 20 seconds. However, on
> longer replications the user is thinking the application
> is locking up. Thus my idea of creating a progress bar.
>
> I have created a mfc dll that 1st prompt the user if
> replication should occur. I am doing this part in a model
> dialog. If the user replies yes than I am creating a
> modeless dialog to display the progress bar. My problem is
> I do not know how to get v1 to the progress bar now.
>
> Should the callback routines be in the class supporting
> the modeless dialog or in the class that creates the
> modeless dialog?
>
> How does a worker thread communicate the static v1 to the
> progress bar??
>
> Thanks for your help..
>
> TPS
>
>
> <Volker Barth> wrote in message
> upwards. >
TPS

2006-01-05, 8:24 pm

Volker

Thanks again for the help...

It appears now that I have the progress bar updating. The onlyissue that I
have left is that it appears to do nothing while recieving messages and than
progresses along while scanning the transaction logs and sending messages.

replicateStruct.progress_index_rtn =
(SET_PROGRESS_CALLBA
CK)ProgIndexCallBack
;

Is this used to track both sends and recieves?

Tracing the executions shows the progress bar is getting updated as the
callback gets entered. However, it does not appear the the callback is
getting entered during the recieve portion of the replication

------------------------------------------------------------------
replicateStruct.transaction_logs = transactionLogs;
replicateStruct.receive = 1;
replicateStruct.send = 1;
replicateStruct.verbose = 1;
replicateStruct.deleted = 1;
replicateStruct.apply = 1;
replicateStruct.batch = 1;
replicateStruct.more = 1;
replicateStruct.triggers = 0;
replicateStruct.debug = 1;
replicateStruct.rename_log = 1; //1
replicateStruct.latest_backup = 0; //1
replicateStruct.scan_log = 0;
replicateStruct.link_debug = 1;
replicateStruct.full_q_scan = 0;
replicateStruct.no_user_interaction = 1;
replicateStruct.unused = 0;
replicateStruct.max_length = 50000;
replicateStruct.memory = 8 * 1024 * 1024; // 2*
replicateStruct.argv = NULL;
-------------------------------------------------------------------

Thanks..
TPS



<Volker Barth> wrote in message news:43bd5110.70a7.1681692777@sybase.com...[color=darkred]
> Hi TPS,
>
> as I told you yesterday I try to give some hints on our
> implementation. I will not give much code samples because
> some parts are coded in German language, and because there
> would be too many irrelevant aspects for a sample. Instead I
> will try to describe the main topics.
>
> Preface: I don't think that is it the best way the wanted
> result can be achieved - but at least it is working ;-)
> And of course this is much more stuff on MFC than on ASA -
> the newsgroup may forgive...
>
>
> In contrast to what I told in my first post, we use a modal
> dialog, not a modeless one. But we use a worker thread for
> the DBTools calls, so the modal dialog stays "reactive"
> while the replication takes place.
>
> 1. Our app is a dialog-based MFC app; as such it uses a
> modal dialog.
> This dialog has a bunch of controls, and one is the progress
> bar - say m_prgStatus.
>
> 2. When the user clicks a "Start" button, the dialog box
> creates a worker thread. This is implemented as a static
> method of the dialog with the following signature:
> static UINT DoTheWork(LPVOID lParam);
> In MFC, this function must be a static method or global
> function, cf. the MFC docs.
> As the only parameter DoTheWork() gets the HWND of the
> dialog.
> So the OnStart()-handler looks something like:
>
> void CMyDlg::OnOK()
> {
> CWinThread* pThread = AfxBeginThread(CMyDl
g::DoTheWork,
> LPVOID(GetSafeHwnd()
));
> ASSERT(pThread);
> }
>
> The use of a worker thread leads to the following situation:
> The main thread is still handling the dialog's message loop,
> e.g. the user can still interact with the dialog (and
> possibly click on a "Abort" button).
> In the meantime, the worker thread is doing his length work
> in the background (and now and then checks the dialog's
> abort state and comes to a clean end then).
>
> 3. The thread function does all the long work (by calls to
> different "worker classes"), e.g. loading the db, connecting
> to our comany's network, downloading the files for DBRemote
> and the like.
> One part is the call to DBRemoteSQL with the according
> callbacks.
> They are part of the corresponding worker class but do
> nothing special (and like thread function, they must be
> implemented as static methods or global functions).
>
> E.g., the progress callback is something like:
>
> (static) short
> CReplManager::OnDbto
olProgressIndexCallb
ack(unsigned long
> lCurIndex,
> unsigned long lMaxIndex)
> {
> static unsigned long lMaxPart = 100;
> if (lMaxIndex > 0)
> {
> lMaxPart = lMaxIndex;
> NotifyProgress(0);
> }
> else
> {
> unsigned long lPercent = (lMaxPart > 0) ? ((lCurIndex *
> 100) / lMaxPart) : 0;
> NotifyProgress(lPerc
ent);
> }
> return 0;
> }
>
> 4. Internally, NotifyProgress() uses SendMessage to send a
> user-defined message to the HWND of the dialog. As WPARAM,
> the value of "lPercent" is given, which is the "normalized
> value" of your "v1" parameter (e.g. with values between 0
> and 100).
> The dialog itself has an handler for this user-defined
> message and looks something like:
> m_prgStatus.SetPos(nPrgStatus);
>
> 5. As its last action, the worker thread function posts a
> message to the dialog that it has finished.
> ::PostMessage(m_hDlg
, UM_WORK_FINISHED, bSuccess, 0L);
> return nReturn;
>
> 6. The dialog has an according handler for this user-defined
> message and displays its "I'm ready for more work" state.
>
>
> So the DBTools calls are all done inside the worker thread,
> whereas the UI is handled within the main thread.
> One point is worth adding: In MFC, different threads can't
> use the same message maps for CWnd-objects - therefore the
> worker thread uses HWNDs instead if CWnd*.
>
>
> TPS, I hope this might give you some advice.
> I' m back on work on Monday, in case of further questions.
>
> Best regards
>
> Volker
>
> TPS wrote:


Volker Barth

2006-01-09, 3:23 am

Hi TPS,

I'm glad to hear that the progress bar is working.

The issue with the callback starting during the scanning
phase sounds familiar to me. At the moment I don't have a
test case with a replication that takes place longer so I
can't check it but I remember that the progress bar
typically seems to start "late" in the replication process.

As I'm not an ASA insider, I suggest that you post this as a
separate topic. Surely one of the iAnywhere guys like Rob or
Reg know the answer.

Regards
Volker

TPS wrote:[color=darkred
]
> Volker
>
> Thanks again for the help...
>
> It appears now that I have the progress bar updating. The
> onlyissue that I have left is that it appears to do
> nothing while recieving messages and than progresses
> along while scanning the transaction logs and sending
> messages.
>
> replicateStruct.progress_index_rtn =
> (SET_PROGRESS_CALLBA
CK)ProgIndexCallBack
;
>
> Is this used to track both sends and recieves?
>
> Tracing the executions shows the progress bar is getting
> updated as the callback gets entered. However, it does
> not appear the the callback is getting entered during the
> recieve portion of the replication
>
> ----------------------------------------------------------
> --------
> replicateStruct.transaction_logs = transactionLogs;
> replicateStruct.receive = 1;
> replicateStruct.send = 1;
> replicateStruct.verbose = 1;
> replicateStruct.deleted = 1;
> replicateStruct.apply = 1;
> replicateStruct.batch = 1;
> replicateStruct.more = 1;
> replicateStruct.triggers = 0;
> replicateStruct.debug = 1;
> replicateStruct.rename_log = 1; //1
> replicateStruct.latest_backup = 0; //1
> replicateStruct.scan_log = 0;
> replicateStruct.link_debug = 1;
> replicateStruct.full_q_scan = 0;
> replicateStruct.no_user_interaction = 1;
> replicateStruct.unused = 0;
> replicateStruct.max_length = 50000;
> replicateStruct.memory = 8 * 1024 * 1024; // 2*
> replicateStruct.argv = NULL;
> ----------------------------------------------------------
> ---------
>
> Thanks..
> TPS
>
>
>
> <Volker Barth> wrote in message
> more work" state. >
> CWnd*. >
> questions. >
> implement >> a worker thread properly to get th v1 value
> to the >> progress control.
> indincating >> that the replication is processing. This
> works great when >> the replication takes less than 20
> seconds. However, on >> longer replications the user is
> thinking the application >> is locking up. Thus my idea
> of creating a progress bar. >>
> model >> dialog. If the user replies yes than I am
> creating a >> modeless dialog to display the progress bar.
> My problem is >> I do not know how to get v1 to the
> progress bar now. >>
> the >> progress bar??
Sponsored Links





Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive | Programming forum archive

Copyright 2008 droptable.com