While the mouse is reach in events (Click, DblClick, MouseDown, MouseUp, MouseMove, etc.) the keyboard is very poor in such events.
Keypress can be associated with KeyDown, but for keyUp there is no such an event.
A solution is to use Bindevent() to bind the WM_KEYUP message
PUBLIC ofrm
ofrm = CREATEOBJECT("MyForm")
SET SYSMENU OFF
ofrm.show()
DEFINE CLASS MyForm as Form
ADD OBJECT txt as textbox
ADD OBJECT cmd as commandbutton WITH top = 50
PROCEDURE Init
* BINDEVENT(This.HWnd,0x0101,This,"detectkeyup") && intercept keyup
BINDEVENT(_vfp.HWnd,0x0101,This,"detectkeyup") && intercept keyup
ENDPROC
PROCEDURE detectkeyup
LPARAMETERS p1,p2,p3,p4
* p1 = ThisForm.hwnd
* p2 - The message; 257 = 0x101 in this case
* p3 = Virtual-key code
* p4 % 65536 - the number of times the keystroke is autorepeated as a result of the user holding down the key. The repeat count is always 1 for a WM_KEYUP message
* FLOOR(p4 / 65536) % 256 - The scan code. The value depends on the OEM.
* BITTEST(p4, 24) - ndicates whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is .t. if it is an extended key; otherwise, it is .f.
IF TYPE("This.ActiveControl") = "U"
lcObj = "ThisForm"
ELSE
lcObj = This.ActiveControl.Name
ENDIF
ACTIVATE SCREEN
? lcObj,"Virtual-key code",p3,"The scan code",FLOOR(p4 / 65536) % 256,IIF(BITTEST(p4, 24),"Extended key","Normal key")
ENDPROC
ENDDEFINE
One final note: WM_KEYDOWN is almost identical, but the value of the message is 0x0100, not 0x0101
Biblio
http://www.foxite.com/archives/detect-keypress-release-0000424382.htm
http://www.tek-tips.com/faqs.cfm?fid=7701
https://msdn.microsoft.com/en-us/library/windows/desktop/ms646281%28v=vs.85%29.aspx
http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
https://msdn.microsoft.com/en-us/library/aa925780.aspx
Related posts
http://praisachion.blogspot.com/2017/08/easter-eggs-4.html
http://praisachion.blogspot.com/2017/08/easter-eggs-3.html
http://praisachion.blogspot.com/2017/08/easter-eggs-2.html
http://praisachion.blogspot.com/2017/08/easter-eggs-1.html
http://praisachion.blogspot.com/2016/02/interceptin-ctrlshiftenter.html
http://praisachion.blogspot.com/2015/06/detect-keyup-like-mouseup.html
http://praisachion.blogspot.com/2015/01/how-can-i-prevent-undocking-docked-form.html
Faceți căutări pe acest blog
luni, 22 iunie 2015
duminică, 14 iunie 2015
Enable / disable form's scrollbars
The EnableScrollBar API allows to enable or disable scrollbars.
It can be enabled or disabled all of them or only some of them.
The documentation claims that the minimum OS must be Vista.
***************
* Begin code
***************
# DEFINE SB_BOTH 3
# DEFINE SB_HORZ 0
# DEFINE SB_VERT 1
# DEFINE ESB_DISABLE_BOTH 3
# DEFINE ESB_DISABLE_DOWN 2
# DEFINE ESB_DISABLE_LEFT 1
# DEFINE ESB_DISABLE_LTUP 1
# DEFINE ESB_DISABLE_RIGHT 2
# DEFINE ESB_DISABLE_RTDN 2
# DEFINE ESB_DISABLE_UP 1
# DEFINE ESB_ENABLE_BOTH 0
DECLARE INTEGER EnableScrollBar IN user32 INTEGER hwnd, INTEGER wSBflags, INTEGER wArrows
PUBLIC ofrm
ofrm = CREATEOBJECT("MyForm")
ofrm.show()
DEFINE CLASS myform as Form
scrollbars = 3
ADD OBJECT edt as editbox WITH left=100,top=100,width=400,height=400,value=REPLICATE("Disco, Duhamel"+CHR(13),40)
ADD OBJECT chk as checkbox WITH value=.T.,caption='Enabled'
PROCEDURE chk.interactivechange
IF This.Value
EnableScrollBar(ThisForm.HWnd,SB_BOTH,ESB_ENABLE_BOTH)
ELSE
EnableScrollBar(ThisForm.HWnd,SB_BOTH,ESB_DISABLE_BOTH )
ENDIF
ENDPROC
ENDDEFINE
***************
* End code
***************
Biblio
http://www.cs.uofs.edu/~beidler/Ada/win32/win32-winuser.html
https://msdn.microsoft.com/en-us/library/windows/desktop/bb787579%28v=vs.85%29.aspx
It can be enabled or disabled all of them or only some of them.
The documentation claims that the minimum OS must be Vista.
***************
* Begin code
***************
# DEFINE SB_BOTH 3
# DEFINE SB_HORZ 0
# DEFINE SB_VERT 1
# DEFINE ESB_DISABLE_BOTH 3
# DEFINE ESB_DISABLE_DOWN 2
# DEFINE ESB_DISABLE_LEFT 1
# DEFINE ESB_DISABLE_LTUP 1
# DEFINE ESB_DISABLE_RIGHT 2
# DEFINE ESB_DISABLE_RTDN 2
# DEFINE ESB_DISABLE_UP 1
# DEFINE ESB_ENABLE_BOTH 0
DECLARE INTEGER EnableScrollBar IN user32 INTEGER hwnd, INTEGER wSBflags, INTEGER wArrows
PUBLIC ofrm
ofrm = CREATEOBJECT("MyForm")
ofrm.show()
DEFINE CLASS myform as Form
scrollbars = 3
ADD OBJECT edt as editbox WITH left=100,top=100,width=400,height=400,value=REPLICATE("Disco, Duhamel"+CHR(13),40)
ADD OBJECT chk as checkbox WITH value=.T.,caption='Enabled'
PROCEDURE chk.interactivechange
IF This.Value
EnableScrollBar(ThisForm.HWnd,SB_BOTH,ESB_ENABLE_BOTH)
ELSE
EnableScrollBar(ThisForm.HWnd,SB_BOTH,ESB_DISABLE_BOTH )
ENDIF
ENDPROC
ENDDEFINE
***************
* End code
***************
Biblio
http://www.cs.uofs.edu/~beidler/Ada/win32/win32-winuser.html
https://msdn.microsoft.com/en-us/library/windows/desktop/bb787579%28v=vs.85%29.aspx
Using GetLocaleInfo and GetLocaleInfoEx for currencies (3) HTML example
In a similar way, a HTML document can be created.
First, the GetLocaleInfo example.
****************
* Begin code
****************
Declare INTEGER GetLocaleInfo in Win32API LONG Locale, LONG LCType, STRING @LpLCData, INTEGER cchData
LOCAL LpLCData,cchData,nretval,lni,lcPos,lcSetPoint,lcPoint,lcSetSep,lcSep,lcSetDec,lcDec,lcNumber,lcCurr,lcStr
LpLCData = space(255) && Address of buffer information.
cchData = LEN(LpLCData) && Size of buffer, LpLCData.
nretval = 0 && Number returned from API call.
RAND(-1)
**************
lcSetPoint = SET("Point")
lcSetSep = SET("Separator")
lcSetDec = SET("Decimals")
*
nretval = GetLocaleInfo(1024, 0x16, @LpLCData, cchData)
lcPoint = LEFT(LpLCData,nretval-1)
SET POINT TO lcPoint
nretval = GetLocaleInfo(1024, 0x17, @LpLCData, cchData)
lcSep = LEFT(LpLCData,nretval-1)
SET SEPARATOR TO lcSep
nretval = GetLocaleInfo(1024, 0x19, @LpLCData, cchData)
lcDec = LEFT(LpLCData,nretval-1)
SET DECIMALS TO &lcDec
nretval = GetLocaleInfo(1024, 0x14, @LpLCData, cchData)
lcCurr = LEFT(LpLCData,nretval-1)
nretval = GetLocaleInfo(1024, 0x1B, @LpLCData, cchData)
lcPos = LEFT(LpLCData,nretval-1)
lcNumber = ALLTRIM(TRANSFORM(1000000 * RAND(),"###" + REPLICATE(",###" , 4) + "." + REPLICATE("9",VAL(m.lcDec))))
lcStr = [<!DOCTYPE html><html><body>]
DO CASE
CASE lcPos = "0"
lcStr = m.lcStr + m.lcCurr + m.lcNumber
CASE lcPos = "1"
lcStr = m.lcStr + m.lcNumber + m.lcCurr
CASE lcPos = "2"
lcStr = m.lcStr + m.lcCurr + " " + m.lcNumber
CASE lcPos = "3"
lcStr = m.lcStr + m.lcNumber + " " + m.lcCurr
ENDCASE
lcStr = m.lcStr + [</body></html>]
STRTOFILE(m.lcStr,"test.htm")
SET POINT TO lcSetPoint
SET SEPARATOR TO lcSetSep
SET DECIMALS TO &lcSetDec
****************
* End code
****************
Obviously, because of Unicode the GetLocaleInfoEx example is a little more complicated.
Note the reversed order of the two UNICODE bytes, between Word and HTML
****************
* Begin code
****************
Declare INTEGER GetLocaleInfoEx in Win32API String Locale, LONG LCType, STRING @LpLCData, INTEGER cchData
LOCAL LpLCData,cchData,nretval,lni,lcPos,lcSetPoint,lcPoint,lcSetSep,lcSep,lcSetDec,lcDec,lcNumber,lcCurrh,lcStrex
LpLCData = space(255) && Address of buffer information.
cchData = LEN(LpLCData) && Size of buffer, LpLCData.
nretval = 0 && Number returned from API call.
RAND(-1)
**************
lcSetPoint = SET("Point")
lcSetSep = SET("Separator")
lcSetDec = SET("Decimals")
*
nretval = GetLocaleInfoEx(Null, 0x16, @LpLCData, cchData)
lcPoint = LEFT(LpLCData,nretval-1)
SET POINT TO lcPoint
nretval = GetLocaleInfoEx(Null, 0x17, @LpLCData, cchData)
lcSep = LEFT(LpLCData,nretval-1)
SET SEPARATOR TO lcSep
nretval = GetLocaleInfoEx(Null, 0x19, @LpLCData, cchData)
lcDec = LEFT(LpLCData,nretval-1)
SET DECIMALS TO &lcDec
nretval = GetLocaleInfoEx(Null, 0x14, @LpLCData, cchData)
lcCurrh = ""
FOR lni = 1 TO nretval-1
lcCurrh = m.lcCurrh + "&#x" + RIGHT(TRANSFORM(ASC(SUBSTR(LpLCData,2*lni)),"@0"),2) + RIGHT(TRANSFORM(ASC(SUBSTR(LpLCData,2*lni-1)),"@0"),2) + ";"
NEXT
nretval = GetLocaleInfoEx(Null, 0x1B, @LpLCData, cchData)
lcPos = LEFT(LpLCData,nretval-1)
lcNumber = ALLTRIM(TRANSFORM(1000000 * RAND(),"###" + REPLICATE(",###" , 4) + "." + REPLICATE("9",VAL(m.lcDec))))
lcStrex = [<!DOCTYPE html><html><body>]
DO CASE
CASE lcPos = "0"
lcStrex = m.lcStrex + m.lcCurrh + m.lcNumber
CASE lcPos = "1"
lcStrex = m.lcStrex + m.lcNumber + m.lcCurrh
CASE lcPos = "2"
lcStrex = m.lcStrex + m.lcCurrh + " " + m.lcNumber
CASE lcPos = "3"
lcStrex = m.lcStrex + m.lcNumber + " " + m.lcCurrh
ENDCASE
lcStrex = m.lcStrex + [</body></html>]
STRTOFILE(m.lcStrex,"testex.htm")
SET POINT TO lcSetPoint
SET SEPARATOR TO lcSetSep
SET DECIMALS TO &lcSetDec
****************
* End code
****************
Related posts
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex_79.html
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex_14.html
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex.html
First, the GetLocaleInfo example.
****************
* Begin code
****************
Declare INTEGER GetLocaleInfo in Win32API LONG Locale, LONG LCType, STRING @LpLCData, INTEGER cchData
LOCAL LpLCData,cchData,nretval,lni,lcPos,lcSetPoint,lcPoint,lcSetSep,lcSep,lcSetDec,lcDec,lcNumber,lcCurr,lcStr
LpLCData = space(255) && Address of buffer information.
cchData = LEN(LpLCData) && Size of buffer, LpLCData.
nretval = 0 && Number returned from API call.
RAND(-1)
**************
lcSetPoint = SET("Point")
lcSetSep = SET("Separator")
lcSetDec = SET("Decimals")
*
nretval = GetLocaleInfo(1024, 0x16, @LpLCData, cchData)
lcPoint = LEFT(LpLCData,nretval-1)
SET POINT TO lcPoint
nretval = GetLocaleInfo(1024, 0x17, @LpLCData, cchData)
lcSep = LEFT(LpLCData,nretval-1)
SET SEPARATOR TO lcSep
nretval = GetLocaleInfo(1024, 0x19, @LpLCData, cchData)
lcDec = LEFT(LpLCData,nretval-1)
SET DECIMALS TO &lcDec
nretval = GetLocaleInfo(1024, 0x14, @LpLCData, cchData)
lcCurr = LEFT(LpLCData,nretval-1)
nretval = GetLocaleInfo(1024, 0x1B, @LpLCData, cchData)
lcPos = LEFT(LpLCData,nretval-1)
lcNumber = ALLTRIM(TRANSFORM(1000000 * RAND(),"###" + REPLICATE(",###" , 4) + "." + REPLICATE("9",VAL(m.lcDec))))
lcStr = [<!DOCTYPE html><html><body>]
DO CASE
CASE lcPos = "0"
lcStr = m.lcStr + m.lcCurr + m.lcNumber
CASE lcPos = "1"
lcStr = m.lcStr + m.lcNumber + m.lcCurr
CASE lcPos = "2"
lcStr = m.lcStr + m.lcCurr + " " + m.lcNumber
CASE lcPos = "3"
lcStr = m.lcStr + m.lcNumber + " " + m.lcCurr
ENDCASE
lcStr = m.lcStr + [</body></html>]
STRTOFILE(m.lcStr,"test.htm")
SET POINT TO lcSetPoint
SET SEPARATOR TO lcSetSep
SET DECIMALS TO &lcSetDec
****************
* End code
****************
Obviously, because of Unicode the GetLocaleInfoEx example is a little more complicated.
Note the reversed order of the two UNICODE bytes, between Word and HTML
****************
* Begin code
****************
Declare INTEGER GetLocaleInfoEx in Win32API String Locale, LONG LCType, STRING @LpLCData, INTEGER cchData
LOCAL LpLCData,cchData,nretval,lni,lcPos,lcSetPoint,lcPoint,lcSetSep,lcSep,lcSetDec,lcDec,lcNumber,lcCurrh,lcStrex
LpLCData = space(255) && Address of buffer information.
cchData = LEN(LpLCData) && Size of buffer, LpLCData.
nretval = 0 && Number returned from API call.
RAND(-1)
**************
lcSetPoint = SET("Point")
lcSetSep = SET("Separator")
lcSetDec = SET("Decimals")
*
nretval = GetLocaleInfoEx(Null, 0x16, @LpLCData, cchData)
lcPoint = LEFT(LpLCData,nretval-1)
SET POINT TO lcPoint
nretval = GetLocaleInfoEx(Null, 0x17, @LpLCData, cchData)
lcSep = LEFT(LpLCData,nretval-1)
SET SEPARATOR TO lcSep
nretval = GetLocaleInfoEx(Null, 0x19, @LpLCData, cchData)
lcDec = LEFT(LpLCData,nretval-1)
SET DECIMALS TO &lcDec
nretval = GetLocaleInfoEx(Null, 0x14, @LpLCData, cchData)
lcCurrh = ""
FOR lni = 1 TO nretval-1
lcCurrh = m.lcCurrh + "&#x" + RIGHT(TRANSFORM(ASC(SUBSTR(LpLCData,2*lni)),"@0"),2) + RIGHT(TRANSFORM(ASC(SUBSTR(LpLCData,2*lni-1)),"@0"),2) + ";"
NEXT
nretval = GetLocaleInfoEx(Null, 0x1B, @LpLCData, cchData)
lcPos = LEFT(LpLCData,nretval-1)
lcNumber = ALLTRIM(TRANSFORM(1000000 * RAND(),"###" + REPLICATE(",###" , 4) + "." + REPLICATE("9",VAL(m.lcDec))))
lcStrex = [<!DOCTYPE html><html><body>]
DO CASE
CASE lcPos = "0"
lcStrex = m.lcStrex + m.lcCurrh + m.lcNumber
CASE lcPos = "1"
lcStrex = m.lcStrex + m.lcNumber + m.lcCurrh
CASE lcPos = "2"
lcStrex = m.lcStrex + m.lcCurrh + " " + m.lcNumber
CASE lcPos = "3"
lcStrex = m.lcStrex + m.lcNumber + " " + m.lcCurrh
ENDCASE
lcStrex = m.lcStrex + [</body></html>]
STRTOFILE(m.lcStrex,"testex.htm")
SET POINT TO lcSetPoint
SET SEPARATOR TO lcSetSep
SET DECIMALS TO &lcSetDec
****************
* End code
****************
Related posts
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex_79.html
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex_14.html
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex.html
Using GetLocaleInfo and GetLocaleInfoEx for currencies (2) Word automation example
The information given by GetLocaleInfo and GetLocaleInfoEx, can be used to write formatted numbers in Word, using automation.
The first example use GetLocaleInfo
Because the values returned by GetLocaleInfo are ASCII, it's easy to use them.
****************
* Begin code
****************
Declare INTEGER GetLocaleInfo in Win32API LONG Locale, LONG LCType, STRING @LpLCData, INTEGER cchData
LOCAL LpLCData,cchData,nretval,lni,lcCurr,lcPos,lcSetPoint,lcPoint,lcSetSep,lcSep,lcSetDec,lcDec,lcNumber,oWrd,oDoc,oRange
LCData = space(255) && Address of buffer information.
cchData = LEN(LpLCData) && Size of buffer, LpLCData.
nretval = 0 && Number returned from API call.
RAND(-1)
**************
lcSetPoint = SET("Point")
lcSetSep = SET("Separator")
lcSetDec = SET("Decimals")
oWrd = CREATEOBJECT("Word.application")
oDoc = oWrd.documents.add()
orange=odoc.range()
*
nretval = GetLocaleInfo(1024, 0x16, @LpLCData, cchData)
lcPoint = LEFT(LpLCData,nretval-1)
SET POINT TO lcPoint
nretval = GetLocaleInfo(1024, 0x17, @LpLCData, cchData)
lcSep = LEFT(LpLCData,nretval-1)
SET SEPARATOR TO lcSep
nretval = GetLocaleInfo(1024, 0x19, @LpLCData, cchData)
lcDec = LEFT(LpLCData,nretval-1)
SET DECIMALS TO &lcDec
nretval = GetLocaleInfo(1024, 0x14, @LpLCData, cchData)
lcCurr = LEFT(LpLCData,nretval-1)
nretval = GetLocaleInfo(1024, 0x1B, @LpLCData, cchData)
lcPos = LEFT(LpLCData,nretval-1)
lcNumber = ALLTRIM(TRANSFORM(1000000 * RAND(),"###" + REPLICATE(",###" , 4) + "." + REPLICATE("9",VAL(m.lcDec))))
DO CASE
CASE lcPos = "0"
orange.text = m.lcCurr + m.lcNumber
CASE lcPos = "1"
orange.text = m.lcNumber + m.lcCurr
CASE lcPos = "2"
orange.text = m.lcCurr + " " + m.lcNumber
CASE lcPos = "3"
orange.text = m.lcNumber + " " + m.lcCurr
ENDCASE
oWrd.visible = .T.
SET POINT TO lcSetPoint
SET SEPARATOR TO lcSetSep
SET DECIMALS TO &lcSetDec
****************
* End code
****************
The second example use GetLocaleInfoEx
Because the values returned by GetLocaleInfoEx are UNICODE, it's a little more complicated.
Each UNICODE character has two bytes, and to because it's easier to insert strings into Word, I build up a blob constant.
****************
* Begin code
****************
Declare INTEGER GetLocaleInfoEx in Win32API String Locale, LONG LCType, STRING @LpLCData, INTEGER cchData
LOCAL LpLCData,cchData,nretval,lni,lcCurr,lcPos,lcSetPoint,lcPoint,lcSetSep,lcSep,lcSetDec,lcDec,lcNumber,oWrd,oDoc,oRange
LCData = space(255) && Address of buffer information.
cchData = LEN(LpLCData) && Size of buffer, LpLCData.
nretval = 0 && Number returned from API call.
RAND(-1)
**************
lcSetPoint = SET("Point")
lcSetSep = SET("Separator")
lcSetDec = SET("Decimals")
oWrd = CREATEOBJECT("Word.application")
oDoc = oWrd.documents.add()
orange=odoc.range()
*
nretval = GetLocaleInfoEx(Null, 0x16, @LpLCData, cchData)
lcPoint = LEFT(LpLCData,nretval-1)
SET POINT TO lcPoint
nretval = GetLocaleInfoEx(Null, 0x17, @LpLCData, cchData)
lcSep = LEFT(LpLCData,nretval-1)
SET SEPARATOR TO lcSep
nretval = GetLocaleInfoEx(Null, 0x19, @LpLCData, cchData)
lcDec = LEFT(LpLCData,nretval-1)
SET DECIMALS TO &lcDec
nretval = GetLocaleInfoEx(Null, 0x14, @LpLCData, cchData)
lcCurr = "0h"
FOR lni = 1 TO nretval-1
lcCurr = m.lcCurr + RIGHT(TRANSFORM(ASC(SUBSTR(LpLCData,2*lni-1)),"@0"),2) + RIGHT(TRANSFORM(ASC(SUBSTR(LpLCData,2*lni)),"@0"),2)
NEXT
nretval = GetLocaleInfoEx(Null, 0x1B, @LpLCData, cchData)
lcPos = LEFT(LpLCData,nretval-1)
lcNumber = ALLTRIM(TRANSFORM(1000000 * RAND(),"###" + REPLICATE(",###" , 4) + "." + REPLICATE("9",VAL(m.lcDec))))
DO CASE
CASE lcPos = "0"
orange.text = EVALUATE(m.lcCurr)
orange.insertafter(m.lcNumber)
CASE lcPos = "1"
orange.text = m.lcNumber
orange.insertafter(EVALUATE(m.lcCurr))
CASE lcPos = "2"
orange.text = EVALUATE(m.lcCurr)
orange.insertafter(" " + m.lcNumber)
CASE lcPos = "3"
orange.text = m.lcNumber + " "
orange.insertafter(EVALUATE(m.lcCurr))
ENDCASE
oWrd.visible = .T.
SET POINT TO lcSetPoint
SET SEPARATOR TO lcSetSep
SET DECIMALS TO &lcSetDec
****************
* End code
****************
Related posts
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex_79.html
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex_14.html
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex.html
The first example use GetLocaleInfo
Because the values returned by GetLocaleInfo are ASCII, it's easy to use them.
****************
* Begin code
****************
Declare INTEGER GetLocaleInfo in Win32API LONG Locale, LONG LCType, STRING @LpLCData, INTEGER cchData
LOCAL LpLCData,cchData,nretval,lni,lcCurr,lcPos,lcSetPoint,lcPoint,lcSetSep,lcSep,lcSetDec,lcDec,lcNumber,oWrd,oDoc,oRange
LCData = space(255) && Address of buffer information.
cchData = LEN(LpLCData) && Size of buffer, LpLCData.
nretval = 0 && Number returned from API call.
RAND(-1)
**************
lcSetPoint = SET("Point")
lcSetSep = SET("Separator")
lcSetDec = SET("Decimals")
oWrd = CREATEOBJECT("Word.application")
oDoc = oWrd.documents.add()
orange=odoc.range()
*
nretval = GetLocaleInfo(1024, 0x16, @LpLCData, cchData)
lcPoint = LEFT(LpLCData,nretval-1)
SET POINT TO lcPoint
nretval = GetLocaleInfo(1024, 0x17, @LpLCData, cchData)
lcSep = LEFT(LpLCData,nretval-1)
SET SEPARATOR TO lcSep
nretval = GetLocaleInfo(1024, 0x19, @LpLCData, cchData)
lcDec = LEFT(LpLCData,nretval-1)
SET DECIMALS TO &lcDec
nretval = GetLocaleInfo(1024, 0x14, @LpLCData, cchData)
lcCurr = LEFT(LpLCData,nretval-1)
nretval = GetLocaleInfo(1024, 0x1B, @LpLCData, cchData)
lcPos = LEFT(LpLCData,nretval-1)
lcNumber = ALLTRIM(TRANSFORM(1000000 * RAND(),"###" + REPLICATE(",###" , 4) + "." + REPLICATE("9",VAL(m.lcDec))))
DO CASE
CASE lcPos = "0"
orange.text = m.lcCurr + m.lcNumber
CASE lcPos = "1"
orange.text = m.lcNumber + m.lcCurr
CASE lcPos = "2"
orange.text = m.lcCurr + " " + m.lcNumber
CASE lcPos = "3"
orange.text = m.lcNumber + " " + m.lcCurr
ENDCASE
oWrd.visible = .T.
SET POINT TO lcSetPoint
SET SEPARATOR TO lcSetSep
SET DECIMALS TO &lcSetDec
****************
* End code
****************
The second example use GetLocaleInfoEx
Because the values returned by GetLocaleInfoEx are UNICODE, it's a little more complicated.
Each UNICODE character has two bytes, and to because it's easier to insert strings into Word, I build up a blob constant.
****************
* Begin code
****************
Declare INTEGER GetLocaleInfoEx in Win32API String Locale, LONG LCType, STRING @LpLCData, INTEGER cchData
LOCAL LpLCData,cchData,nretval,lni,lcCurr,lcPos,lcSetPoint,lcPoint,lcSetSep,lcSep,lcSetDec,lcDec,lcNumber,oWrd,oDoc,oRange
LCData = space(255) && Address of buffer information.
cchData = LEN(LpLCData) && Size of buffer, LpLCData.
nretval = 0 && Number returned from API call.
RAND(-1)
**************
lcSetPoint = SET("Point")
lcSetSep = SET("Separator")
lcSetDec = SET("Decimals")
oWrd = CREATEOBJECT("Word.application")
oDoc = oWrd.documents.add()
orange=odoc.range()
*
nretval = GetLocaleInfoEx(Null, 0x16, @LpLCData, cchData)
lcPoint = LEFT(LpLCData,nretval-1)
SET POINT TO lcPoint
nretval = GetLocaleInfoEx(Null, 0x17, @LpLCData, cchData)
lcSep = LEFT(LpLCData,nretval-1)
SET SEPARATOR TO lcSep
nretval = GetLocaleInfoEx(Null, 0x19, @LpLCData, cchData)
lcDec = LEFT(LpLCData,nretval-1)
SET DECIMALS TO &lcDec
nretval = GetLocaleInfoEx(Null, 0x14, @LpLCData, cchData)
lcCurr = "0h"
FOR lni = 1 TO nretval-1
lcCurr = m.lcCurr + RIGHT(TRANSFORM(ASC(SUBSTR(LpLCData,2*lni-1)),"@0"),2) + RIGHT(TRANSFORM(ASC(SUBSTR(LpLCData,2*lni)),"@0"),2)
NEXT
nretval = GetLocaleInfoEx(Null, 0x1B, @LpLCData, cchData)
lcPos = LEFT(LpLCData,nretval-1)
lcNumber = ALLTRIM(TRANSFORM(1000000 * RAND(),"###" + REPLICATE(",###" , 4) + "." + REPLICATE("9",VAL(m.lcDec))))
DO CASE
CASE lcPos = "0"
orange.text = EVALUATE(m.lcCurr)
orange.insertafter(m.lcNumber)
CASE lcPos = "1"
orange.text = m.lcNumber
orange.insertafter(EVALUATE(m.lcCurr))
CASE lcPos = "2"
orange.text = EVALUATE(m.lcCurr)
orange.insertafter(" " + m.lcNumber)
CASE lcPos = "3"
orange.text = m.lcNumber + " "
orange.insertafter(EVALUATE(m.lcCurr))
ENDCASE
oWrd.visible = .T.
SET POINT TO lcSetPoint
SET SEPARATOR TO lcSetSep
SET DECIMALS TO &lcSetDec
****************
* End code
****************
Related posts
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex_79.html
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex_14.html
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex.html
Using GetLocaleInfo and GetLocaleInfoEx for currencies (1)
GetLocaleInfo and GetLocaleInfoEx can be used to get the local settings for currencies (the ones from Control Panel -> Regional Settings)
Both GetLocaleInfo and GetLocaleInfoEx gives plenty of informations. They can be invoked similarly, and gives similar results.
The main difference between the the functions signature is the first parameter. GetLocaleInfo have a LONG parameter, while GetLocaleInfoEx a character parameter.
GetLocaleInfo can be used in Windows XP, Vista and above. GetLocaleInfo tends to become deprecated.
GetLocaleInfoEx can be used in Windows Vista and above, but cannot be used in Windows XP.
GetLocaleInfo provide ASCII results, while GetLocaleInfoEx supports Unicode.
This means many currencies (like English India) can be obtained only with GetLocaleInfoEx.
To get the values for the default settings, the first parameter of GetLocaleInfoEx must be Null.
For other values, use the format <language> - <REGION>, but converted to Unicode
For example
StrConv ("en-AU", 5) + CHR (0)
or
StrConv ("en-US", 5) + CHR (0)
****************
* Begin code
****************
Declare INTEGER GetLocaleInfo in Win32API LONG Locale, LONG LCType, STRING @LpLCData, INTEGER cchData
Declare INTEGER GetLocaleInfoEx in Win32API String Locale, LONG LCType, STRING @LpLCData, INTEGER cchData
LOCAL LpLCData,cchData,nretval
LpLCData = space(255) && Address of buffer information.
cchData = LEN(LpLCData) && Size of buffer, LpLCData.
nretval = 0 && Number returned from API call.
? "currency symbol - user default"
LPCWSTR = Null
nretval = GetLocaleInfoEx(LPCWSTR, 0x14, @LpLCData, cchData)
?nretval,LpLCData,TRANSFORM(ASC(SUBSTR(LpLCData,2)),"@0"),TRANSFORM(ASC(LpLCData),"@0") && Euro (Unicode 0x20 0x0AC)
? "currency symbol - english - Great Britain"
LPCWSTR = STRCONV("en-GB",5)+CHR(0)
nretval = GetLocaleInfoEx(LPCWSTR, 0x14, @LpLCData, cchData)
?nretval,LpLCData,TRANSFORM(ASC(SUBSTR(LpLCData,2)),"@0"),TRANSFORM(ASC(LpLCData),"@0") && pounds (Unicode 0x000 0x0A3 ou ASCII 0xA3)
? "currency symbol"
nretval = GetLocaleInfo(1024, 0x14, @LpLCData, cchData)
?nretval,LEFT(LpLCData,nretval-1)
nretval = GetLocaleInfoEx(Null, 0x14, @LpLCData, cchData)
?nretval
FOR lni = 1 TO nretval-1
?? TRANSFORM(ASC(SUBSTR(LpLCData,2*lni)),"@0"),TRANSFORM(ASC(SUBSTR(LpLCData,2*lni-1)),"@0")
NEXT
? "currency position"
nretval = GetLocaleInfoEx(Null, 0x1B, @LpLCData, cchData)
?nretval,LpLCData
? "decimal separator"
nretval = GetLocaleInfoEx(Null, 0x16, @LpLCData, cchData)
?nretval,LpLCData
? "thousand separator"
nretval = GetLocaleInfoEx(Null, 0x17, @LpLCData, cchData)
?nretval,LpLCData
? "number of decimals"
nretval = GetLocaleInfoEx(Null, 0x19, @LpLCData, cchData)
?nretval,LpLCData
****************
* End code
****************
Biblio
http://www.foxite.com/archives/getlocaleinfoex-fountain-of-knowledge-0000424218.htm
ftp://ftp.microsoft.com/misc1/DEVELOPR/FOX/KB/Q177/1/46.TXT
https://msdn.microsoft.com/en-us/library/windows/desktop/dd318103%28v=vs.85%29.aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/dd318101%28v=vs.85%29.aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/dd464799%28v=vs.85%29.aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/dd373755%28v=vs.85%29.aspx
http://www.pinvoke.net/default.aspx/kernel32/GetLocaleInfoEx.html
Related posts
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex_79.html
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex_14.html
http://praisachion.blogspot.com/2015/06/using-getlocaleinfo-and-getlocaleinfoex.html
vineri, 24 aprilie 2015
Previewing two or more different reports on the same page
Sometimes you my want to see side by side two or more reports, in the same window.
Possible solutions:
1) Using a mixture of Reportbehavior 80 and Reportbehavior 90
PUBLIC ofrm
ofrm=CREATEOBJECT("MyForm")
ofrm.show()
DEFINE CLASS MyForm as Form
width=1000
height=500
oFrm1=.Null.
oFrm2=.Null.
PROCEDURE load
CREATE CURSOR aa (ii I autoinc,bb C(10) DEFAULT SYS(2015))
FOR lni=1 TO 100
APPEND BLANK
NEXT
CREATE REPORT rep1 FROM aa
SELECT 0
USE rep1.frx
LOCATE FOR objtype=9 AND objcode=1
replace tag WITH [_vfp.docmd("select aa")] && page header On Entry event
USE
CREATE CURSOR bb (jj I autoinc,cc C(10) DEFAULT SYS(2015))
FOR lni=1 TO 100
APPEND BLANK
NEXT
SELECT 0
CREATE REPORT rep2 FROM bb
USE rep2.frx
LOCATE FOR objtype=9 AND objcode=1
replace tag WITH [_vfp.docmd("select bb")] && page header On Entry event
USE
ENDPROC
PROCEDURE init
DEFINE WINDOW win1 FROM 0,0 TO 10,10 NAME ThisForm.ofrm1 IN WINDOW (This.Name)
ThisForm.ofrm1.Name=SYS(2015)
ThisForm.ofrm1.width=500
ThisForm.ofrm1.height=500
DEFINE WINDOW win2 FROM 0,0 TO 10,10 NAME ThisForm.ofrm2 IN WINDOW (This.Name)
ThisForm.ofrm2.Name=SYS(2015)
ThisForm.ofrm2.width=500
ThisForm.ofrm2.height=500
ThisForm.ofrm2.Left=500
ACTIVATE WINDOW (ThisForm.ofrm2.Name)
ACTIVATE WINDOW (ThisForm.ofrm1.Name)
SET REPORTBEHAVIOR 80
SELECT aa
REPORT FORM rep1 PREVIEW WINDOW (ThisForm.ofrm1.Name) IN WINDOW (ThisForm.ofrm1.Name) NOWAIT
SET REPORTBEHAVIOR 90
SELECT bb
REPORT FORM rep2 PREVIEW WINDOW (ThisForm.ofrm2.Name) IN WINDOW (ThisForm.ofrm2.Name) NOWAIT
ENDPROC
PROCEDURE QueryUnload
DEACTIVATE WINDOW (ThisForm.ofrm1.Name)
DEACTIVATE WINDOW (ThisForm.ofrm2.Name)
ThisForm.ofrm1=.Null.
ThisForm.ofrm2=.Null.
CLEAR MEMORY
ENDPROC
ENDDEFINE
2) Displaying three reports, using reportbehavior 90
PUBLIC ofrm
ofrm=CREATEOBJECT("MyForm")
ofrm.show()
DEFINE CLASS MyForm as Form
width=1050
height=500
oFrm1=.Null.
oFrm2=.Null.
oFrm3=.Null.
PROCEDURE load
CREATE CURSOR aa (ii I autoinc,bb C(10) DEFAULT SYS(2015))
FOR lni=1 TO 100
APPEND BLANK
NEXT
CREATE REPORT rep1 FROM aa
SELECT 0
USE rep1.frx
LOCATE FOR objtype=9 AND objcode=1
replace tag WITH [_vfp.docmd("select aa")] && page header On Entry event
USE
CREATE CURSOR bb (jj I autoinc,cc C(10) DEFAULT SYS(2015))
FOR lni=1 TO 100
APPEND BLANK
NEXT
SELECT 0
CREATE REPORT rep2 FROM bb
USE rep2.frx
LOCATE FOR objtype=9 AND objcode=1
replace tag WITH [_vfp.docmd("select bb")] && page header On Entry event
USE
CREATE CURSOR cc (kk I autoinc,dd C(10) DEFAULT SYS(2015))
FOR lni=1 TO 100
APPEND BLANK
NEXT
SELECT 0
CREATE REPORT rep3 FROM cc
USE rep3.frx
LOCATE FOR objtype=9 AND objcode=1
replace tag WITH [_vfp.docmd("select cc")] && page header On Entry event
USE
ENDPROC
PROCEDURE init
DEFINE WINDOW win1 FROM 0,0 TO 10,10 NAME ThisForm.ofrm1 IN WINDOW (This.Name)
ThisForm.ofrm1.Name=SYS(2015)
ThisForm.ofrm1.width=350
ThisForm.ofrm1.height=500
DEFINE WINDOW win2 FROM 0,0 TO 10,10 NAME ThisForm.ofrm2 IN WINDOW (This.Name)
ThisForm.ofrm2.Name=SYS(2015)
ThisForm.ofrm2.width=350
ThisForm.ofrm2.height=500
ThisForm.ofrm2.Left=350
DEFINE WINDOW win3 FROM 0,0 TO 10,10 NAME ThisForm.ofrm3 IN WINDOW (This.Name)
ThisForm.ofrm3.Name=SYS(2015)
ThisForm.ofrm3.width=350
ThisForm.ofrm3.height=500
ThisForm.ofrm3.Left=700
ACTIVATE WINDOW (ThisForm.ofrm1.Name)
ACTIVATE WINDOW (ThisForm.ofrm2.Name)
ACTIVATE WINDOW (ThisForm.ofrm3.Name)
SET REPORTBEHAVIOR 90
LOCAL loRL1,loRL2
loRL1= CREATEOBJECT("ReportListener")
loRL2= CREATEOBJECT("ReportListener")
loRL3= CREATEOBJECT("ReportListener")
STORE 1 TO loRL1.ListenerType,loRL2.ListenerType,loRL3.ListenerType
SELECT aa
REPORT FORM rep1 OBJECT loRL1 WINDOW (ThisForm.ofrm1.Name) IN WINDOW (ThisForm.ofrm1.Name) NOWAIT
SELECT bb
REPORT FORM rep2 OBJECT loRL2 WINDOW (ThisForm.ofrm2.Name) IN WINDOW (ThisForm.ofrm2.Name) NOWAIT
SELECT cc
REPORT FORM rep3 OBJECT loRL3 WINDOW (ThisForm.ofrm3.Name) IN WINDOW (ThisForm.ofrm3.Name) NOWAIT
ENDPROC
PROCEDURE QueryUnload
DEACTIVATE WINDOW (ThisForm.ofrm1.Name)
DEACTIVATE WINDOW (ThisForm.ofrm2.Name)
DEACTIVATE WINDOW (ThisForm.ofrm3.Name)
ThisForm.ofrm1=.Null.
ThisForm.ofrm2=.Null.
ThisForm.ofrm3=.Null.
CLEAR MEMORY
ENDPROC
ENDDEFINE
In both solutions, in the main form were embedded two or more forms (windows), one for each report.
But a more elegant solution is to add two containers in the same form
3) Using the reportbehavior 90 and the report listener
*----------------------------------------------------------------------------------
* Adapted from VFP help topic Creating a Custom Preview Container
* code example: simplepreview.prg
*----------------------------------------------------------------------------------
CREATE CURSOR x1 (ii I autoinc,aa C(10) DEFAULT REPLICATE(CHR(32+ii),10))
FOR lni=1 TO 100
APPEND BLANK
NEXT
CREATE REPORT rep1 FROM x1
CREATE CURSOR x2 (jj I autoinc,bb C(10) DEFAULT REPLICATE(CHR(64+jj),10))
FOR lni=1 TO 50
APPEND BLANK
NEXT
CREATE REPORT rep2 FROM x2
pc = CREATEOBJECT("FormPreview")
rl1 = NEWOBJECT("ReportListener")
rl1.ListenerType = 1 && Buffer all pages, use preview container
rl1.PreviewContainer = pc.SimplePreview1
rl2 = NEWOBJECT("ReportListener")
rl2.ListenerType = 1 && Buffer all pages, use preview container
rl2.PreviewContainer = pc.SimplePreview2
SELECT x1
REPORT FORM rep1 OBJECT rl1 &&NOWAIT
SELECT x2
REPORT FORM rep2 OBJECT rl2 &&NOWAIT
pc.visible=.T.
DEFINE CLASS FormPreview as Form
caption="Click - next, Rightclick - previous page"
width=1000
height=800
ADD OBJECT SimplePreview1 as SimplePreview
ADD OBJECT SimplePreview2 as SimplePreview WITH left=500
PROCEDURE QueryUnload
IF NOT ISNULL( THIS.SimplePreview1.ListenerRef )
THIS.SimplePreview1.ListenerRef.OnPreviewClose(.F.)
THIS.SimplePreview1.ListenerRef = .NULL.
ENDIF
IF NOT ISNULL( THIS.SimplePreview2.ListenerRef )
THIS.SimplePreview2.ListenerRef.OnPreviewClose(.F.)
THIS.SimplePreview2.ListenerRef = .NULL.
ENDIF
THIS.Hide()
NODEFAULT
ENDPROC
PROCEDURE Paint
IF NOT ISNULL( THIS.SimplePreview1.ListenerRef )
THIS.SimplePreview1.ListenerRef.OutputPage( THIS.SimplePreview1.PageNo, THIS.SimplePreview1.Canvas, 2 )
ENDIF
IF NOT ISNULL( THIS.SimplePreview2.ListenerRef )
THIS.SimplePreview2.ListenerRef.OutputPage( THIS.SimplePreview2.PageNo, THIS.SimplePreview2.Canvas, 2 )
ENDIF
ENDPROC
ENDDEFINE
DEFINE CLASS SimplePreview AS Container
ListenerRef = .NULL.
PageNo = 1
width=500
height=800
ADD OBJECT Canvas AS Shape WITH ;
Height = 800, Width = 500
PROCEDURE Canvas.Click
WITH THIS.Parent
IF .PageNo < .ListenerRef.OutputPageCount
.PageNo = .PageNo + 1
.Refresh()
ENDIF
ENDWITH
ENDPROC
PROCEDURE Canvas.RightClick
WITH THIS.Parent
IF .PageNo > 1
.PageNo = .PageNo - 1
.Refresh()
ENDIF
ENDWITH
ENDPROC
PROCEDURE SetReport
LPARAMETER oListenerRef
THIS.ListenerRef = oListenerRef
ENDPROC
ENDDEFINE
Possible solutions:
1) Using a mixture of Reportbehavior 80 and Reportbehavior 90
PUBLIC ofrm
ofrm=CREATEOBJECT("MyForm")
ofrm.show()
DEFINE CLASS MyForm as Form
width=1000
height=500
oFrm1=.Null.
oFrm2=.Null.
PROCEDURE load
CREATE CURSOR aa (ii I autoinc,bb C(10) DEFAULT SYS(2015))
FOR lni=1 TO 100
APPEND BLANK
NEXT
CREATE REPORT rep1 FROM aa
SELECT 0
USE rep1.frx
LOCATE FOR objtype=9 AND objcode=1
replace tag WITH [_vfp.docmd("select aa")] && page header On Entry event
USE
CREATE CURSOR bb (jj I autoinc,cc C(10) DEFAULT SYS(2015))
FOR lni=1 TO 100
APPEND BLANK
NEXT
SELECT 0
CREATE REPORT rep2 FROM bb
USE rep2.frx
LOCATE FOR objtype=9 AND objcode=1
replace tag WITH [_vfp.docmd("select bb")] && page header On Entry event
USE
ENDPROC
PROCEDURE init
DEFINE WINDOW win1 FROM 0,0 TO 10,10 NAME ThisForm.ofrm1 IN WINDOW (This.Name)
ThisForm.ofrm1.Name=SYS(2015)
ThisForm.ofrm1.width=500
ThisForm.ofrm1.height=500
DEFINE WINDOW win2 FROM 0,0 TO 10,10 NAME ThisForm.ofrm2 IN WINDOW (This.Name)
ThisForm.ofrm2.Name=SYS(2015)
ThisForm.ofrm2.width=500
ThisForm.ofrm2.height=500
ThisForm.ofrm2.Left=500
ACTIVATE WINDOW (ThisForm.ofrm2.Name)
ACTIVATE WINDOW (ThisForm.ofrm1.Name)
SET REPORTBEHAVIOR 80
SELECT aa
REPORT FORM rep1 PREVIEW WINDOW (ThisForm.ofrm1.Name) IN WINDOW (ThisForm.ofrm1.Name) NOWAIT
SET REPORTBEHAVIOR 90
SELECT bb
REPORT FORM rep2 PREVIEW WINDOW (ThisForm.ofrm2.Name) IN WINDOW (ThisForm.ofrm2.Name) NOWAIT
ENDPROC
PROCEDURE QueryUnload
DEACTIVATE WINDOW (ThisForm.ofrm1.Name)
DEACTIVATE WINDOW (ThisForm.ofrm2.Name)
ThisForm.ofrm1=.Null.
ThisForm.ofrm2=.Null.
CLEAR MEMORY
ENDPROC
ENDDEFINE
2) Displaying three reports, using reportbehavior 90
PUBLIC ofrm
ofrm=CREATEOBJECT("MyForm")
ofrm.show()
DEFINE CLASS MyForm as Form
width=1050
height=500
oFrm1=.Null.
oFrm2=.Null.
oFrm3=.Null.
PROCEDURE load
CREATE CURSOR aa (ii I autoinc,bb C(10) DEFAULT SYS(2015))
FOR lni=1 TO 100
APPEND BLANK
NEXT
CREATE REPORT rep1 FROM aa
SELECT 0
USE rep1.frx
LOCATE FOR objtype=9 AND objcode=1
replace tag WITH [_vfp.docmd("select aa")] && page header On Entry event
USE
CREATE CURSOR bb (jj I autoinc,cc C(10) DEFAULT SYS(2015))
FOR lni=1 TO 100
APPEND BLANK
NEXT
SELECT 0
CREATE REPORT rep2 FROM bb
USE rep2.frx
LOCATE FOR objtype=9 AND objcode=1
replace tag WITH [_vfp.docmd("select bb")] && page header On Entry event
USE
CREATE CURSOR cc (kk I autoinc,dd C(10) DEFAULT SYS(2015))
FOR lni=1 TO 100
APPEND BLANK
NEXT
SELECT 0
CREATE REPORT rep3 FROM cc
USE rep3.frx
LOCATE FOR objtype=9 AND objcode=1
replace tag WITH [_vfp.docmd("select cc")] && page header On Entry event
USE
ENDPROC
PROCEDURE init
DEFINE WINDOW win1 FROM 0,0 TO 10,10 NAME ThisForm.ofrm1 IN WINDOW (This.Name)
ThisForm.ofrm1.Name=SYS(2015)
ThisForm.ofrm1.width=350
ThisForm.ofrm1.height=500
DEFINE WINDOW win2 FROM 0,0 TO 10,10 NAME ThisForm.ofrm2 IN WINDOW (This.Name)
ThisForm.ofrm2.Name=SYS(2015)
ThisForm.ofrm2.width=350
ThisForm.ofrm2.height=500
ThisForm.ofrm2.Left=350
DEFINE WINDOW win3 FROM 0,0 TO 10,10 NAME ThisForm.ofrm3 IN WINDOW (This.Name)
ThisForm.ofrm3.Name=SYS(2015)
ThisForm.ofrm3.width=350
ThisForm.ofrm3.height=500
ThisForm.ofrm3.Left=700
ACTIVATE WINDOW (ThisForm.ofrm1.Name)
ACTIVATE WINDOW (ThisForm.ofrm2.Name)
ACTIVATE WINDOW (ThisForm.ofrm3.Name)
SET REPORTBEHAVIOR 90
LOCAL loRL1,loRL2
loRL1= CREATEOBJECT("ReportListener")
loRL2= CREATEOBJECT("ReportListener")
loRL3= CREATEOBJECT("ReportListener")
STORE 1 TO loRL1.ListenerType,loRL2.ListenerType,loRL3.ListenerType
SELECT aa
REPORT FORM rep1 OBJECT loRL1 WINDOW (ThisForm.ofrm1.Name) IN WINDOW (ThisForm.ofrm1.Name) NOWAIT
SELECT bb
REPORT FORM rep2 OBJECT loRL2 WINDOW (ThisForm.ofrm2.Name) IN WINDOW (ThisForm.ofrm2.Name) NOWAIT
SELECT cc
REPORT FORM rep3 OBJECT loRL3 WINDOW (ThisForm.ofrm3.Name) IN WINDOW (ThisForm.ofrm3.Name) NOWAIT
ENDPROC
PROCEDURE QueryUnload
DEACTIVATE WINDOW (ThisForm.ofrm1.Name)
DEACTIVATE WINDOW (ThisForm.ofrm2.Name)
DEACTIVATE WINDOW (ThisForm.ofrm3.Name)
ThisForm.ofrm1=.Null.
ThisForm.ofrm2=.Null.
ThisForm.ofrm3=.Null.
CLEAR MEMORY
ENDPROC
ENDDEFINE
In both solutions, in the main form were embedded two or more forms (windows), one for each report.
But a more elegant solution is to add two containers in the same form
3) Using the reportbehavior 90 and the report listener
*----------------------------------------------------------------------------------
* Adapted from VFP help topic Creating a Custom Preview Container
* code example: simplepreview.prg
*----------------------------------------------------------------------------------
CREATE CURSOR x1 (ii I autoinc,aa C(10) DEFAULT REPLICATE(CHR(32+ii),10))
FOR lni=1 TO 100
APPEND BLANK
NEXT
CREATE REPORT rep1 FROM x1
CREATE CURSOR x2 (jj I autoinc,bb C(10) DEFAULT REPLICATE(CHR(64+jj),10))
FOR lni=1 TO 50
APPEND BLANK
NEXT
CREATE REPORT rep2 FROM x2
pc = CREATEOBJECT("FormPreview")
rl1 = NEWOBJECT("ReportListener")
rl1.ListenerType = 1 && Buffer all pages, use preview container
rl1.PreviewContainer = pc.SimplePreview1
rl2 = NEWOBJECT("ReportListener")
rl2.ListenerType = 1 && Buffer all pages, use preview container
rl2.PreviewContainer = pc.SimplePreview2
SELECT x1
REPORT FORM rep1 OBJECT rl1 &&NOWAIT
SELECT x2
REPORT FORM rep2 OBJECT rl2 &&NOWAIT
pc.visible=.T.
DEFINE CLASS FormPreview as Form
caption="Click - next, Rightclick - previous page"
width=1000
height=800
ADD OBJECT SimplePreview1 as SimplePreview
ADD OBJECT SimplePreview2 as SimplePreview WITH left=500
PROCEDURE QueryUnload
IF NOT ISNULL( THIS.SimplePreview1.ListenerRef )
THIS.SimplePreview1.ListenerRef.OnPreviewClose(.F.)
THIS.SimplePreview1.ListenerRef = .NULL.
ENDIF
IF NOT ISNULL( THIS.SimplePreview2.ListenerRef )
THIS.SimplePreview2.ListenerRef.OnPreviewClose(.F.)
THIS.SimplePreview2.ListenerRef = .NULL.
ENDIF
THIS.Hide()
NODEFAULT
ENDPROC
PROCEDURE Paint
IF NOT ISNULL( THIS.SimplePreview1.ListenerRef )
THIS.SimplePreview1.ListenerRef.OutputPage( THIS.SimplePreview1.PageNo, THIS.SimplePreview1.Canvas, 2 )
ENDIF
IF NOT ISNULL( THIS.SimplePreview2.ListenerRef )
THIS.SimplePreview2.ListenerRef.OutputPage( THIS.SimplePreview2.PageNo, THIS.SimplePreview2.Canvas, 2 )
ENDIF
ENDPROC
ENDDEFINE
DEFINE CLASS SimplePreview AS Container
ListenerRef = .NULL.
PageNo = 1
width=500
height=800
ADD OBJECT Canvas AS Shape WITH ;
Height = 800, Width = 500
PROCEDURE Canvas.Click
WITH THIS.Parent
IF .PageNo < .ListenerRef.OutputPageCount
.PageNo = .PageNo + 1
.Refresh()
ENDIF
ENDWITH
ENDPROC
PROCEDURE Canvas.RightClick
WITH THIS.Parent
IF .PageNo > 1
.PageNo = .PageNo - 1
.Refresh()
ENDIF
ENDWITH
ENDPROC
PROCEDURE SetReport
LPARAMETER oListenerRef
THIS.ListenerRef = oListenerRef
ENDPROC
ENDDEFINE
marți, 21 aprilie 2015
Homage to women
Today I understood Saint Francis of Assisi's expression: "Sister Moon and brother Sun".
I went to the balcony, and the Sun was covered by the clouds.
I invited my female colleagues to join me, but they were reluctant, because of cold.
I insisted, saying the Sun itself waits for their arriving.
The moment they joined me, the Sun revealed itself.
After two minutes, my colleagues went back and instantly the Sun has hidden behind the clouds.
I went to the balcony, and the Sun was covered by the clouds.
I invited my female colleagues to join me, but they were reluctant, because of cold.
I insisted, saying the Sun itself waits for their arriving.
The moment they joined me, the Sun revealed itself.
After two minutes, my colleagues went back and instantly the Sun has hidden behind the clouds.
Abonați-vă la:
Postări (Atom)