May 07, 2024, 10:51:45 AM

News:

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


Unable to create child window in a dialog

Started by JoaoAfonso, May 07, 2008, 05:24:39 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

JoaoAfonso

Good morning.
This is another of my problems that for sure has an easy solution I am not seeing. I am trying to create a calendar to select dates inside a dialog. Figured out the best way was create a child window with calendar function. Anyway, when I try to open a window in dialog handler, program freezes and crashes. This worked in CB and I am now translating it to EB.

I call d5 using domodal, maybe it matters.

SUB dhandler5
STRING motivo,gdhi,gdhf,juliani,julianf
WINDOW calendi
dpi=NULL:dpf=NULL
motivo=CHR$(0):gdhi=CHR$(0):gdhf=CHR$(0):juliani=CHR$(0):julianf=CHR$(0)
SELECT @CLASS
CASE @IDINITDIALOG
OPENWINDOW calendi,100,20,232,24,@NOCAPTION|@SYSMENU|@BORDER,d5,"CalendÃÆ'Ã,¡rio inicial",&calendi_handler
CONTROL(calendi,@STATIC,"",10,270,300,15,0x5000010B,10)
dpi=CreateWindowExA(0,"SysDateTimePick32","",@WS_VISIBLE | @WS_CHILD | @dpLongDate ,1,1,230,20,calendi,2024+@dp1,0,0)
checkdate(dpi)
CENTERWINDOW d5
CASE @IDCLOSEWINDOW
CLOSEWINDOW calendi
CLOSEDIALOG d5,@IDCANCEL
CASE @IDCONTROL
SELECT @CONTROLID
CASE 1
motivo = GETCONTROLTEXT(d5,6)
IF motivo=""
MESSAGEBOX d5,"Nenhum motivo definido.","AplicaÃÆ'Ã,§ÃÆ'Ã,£o para GestÃÆ'Ã,£o de Actividades - EPI"
ELSE
checkdate(dpi)
CLOSEWINDOW calendi
CLOSEDIALOG d5,@IDOK
ENDIF
CASE 2
CLOSEWINDOW calendi
CLOSEDIALOG d5,@IDCANCEL
ENDSELECT
ENDSELECT
ENDSUB


Thanks in advance...
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

sapero

May 07, 2008, 06:27:56 AM #1 Last Edit: May 07, 2008, 06:42:12 AM by sapero
CreateWindowEx requires a handle, not a pointer to WINDOW structure. If you change the calendi parameter to calendi.hwnd, the window will be created.

A WINDOW or DIALOG structure - if allocated on the stack as you did - can/will be invalidated every time your function is called,
also the .hwnd will be changed by other functions. This applies to any variable type.
WINDOW structure should be unmodified for the lifetime of the window.

If you still need to have it on the stack, after OPENWINDOW you must wait until the calendi window is destroyed:
while (calendi.hwnd <> 0)
   wait
endwhile

Or just move the "WINDOW calendi" line out of the function:
WINDOW calendi
SUB dhandler5

It worked in CB because (probably) any variable of WINDOW type was allocated in global program scope.

JoaoAfonso

How about just this?

SUB dhandler5
STRING motivo,gdhi,gdhf,juliani,julianf
dpi=NULL:dpf=NULL
motivo=CHR$(0):gdhi=CHR$(0):gdhf=CHR$(0):juliani=CHR$(0):julianf=CHR$(0)
SELECT @CLASS
CASE @IDINITDIALOG
CENTERWINDOW d5
dpi=CreateWindowExA(0,"SysDateTimePick32","",@WS_VISIBLE | @WS_CHILD | @dpLongDate ,1,1,230,20,d5.hwnd,2024+@dp1,0,0)
                                CASE 1
                                                gdhi=checkdate(dpi)


The previous code was "adapted" from old projects. This way seems easier and the best for my purposes. It works, data is shown as I want, but problem now is get useful date. How to get the correct date? I use this, but info is not usable this way:

SUB checkdate(dp:UINT),STRING
STRING ano,mes,dia,gdh,julian,theYear,theMonth,theDay
INT temp
SYSTEMTIME mt
ano=CHR$(0):mes=CHR$(0):dia=CHR$(0):gdh=CHR$(0):julian=CHR$(0):theYear=CHR$(0):theMonth=CHR$(0):theDay=CHR$(0)
temp=NULL
SENDMESSAGEA(dp,DTM_GETSYTEMTIME,0,mt)
theYear = LTRIM$(STR$(mt.wYEAR))
ano=right$(theyear,2)
theMonth = LTRIM$(STR$(mt.wMonth))
IF LEN(theMonth) = 1 THEN theMonth = APPEND$("0",theMonth)
if theMonth="01" then mes="JAN"
if theMonth="02" then mes="FEV"
if theMonth="03" then mes="MAR"
if theMonth="04" then mes="ABR"
if theMonth="05" then mes="MAI"
if theMonth="06" then mes="JUN"
if theMonth="07" then mes="JUL"
if theMonth="08" then mes="AGO"
if theMonth="09" then mes="SET"
if theMonth="10" then mes="OUT"
if theMonth="11" then mes="NOV"
if theMonth="12" then mes="DEC"
theDay = LTRIM$(STR$(mt.wDay))
IF LEN(theDay) = 1 THEN theDay = APPEND$("0",theDay)
MESSAGEBOX 0,"theday: "+theday+chr$(13)+"themonth: "+themonth+chr$(13)+"mes: "+mes+chr$(13)+"theyear: "+theyear+chr$(13),"ni"
gdh=theDay+mes+ano
temp=julian(theDay+theMonth+theYear)
RETURN gdh+LTRIM$(STR$(temp))
ENDSUB


This messagebox is there just to keep tracking of variables. Thank you again.
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

sapero

Play a bit with this console example, maybe you find what you need:
declare import, GetDateFormatA(int locale, int flags, pointer date, string format, string out, int outlen)
declare import, GetLocalTime(pointer time)
declare extern __getch()

type SYSTEMTIME
   WORD wYear: WORD wMonth: WORD wDayOfWeek: WORD wDay: WORD wHour: WORD wMinute: WORD wSecond: WORD wMilliseconds
endtype


SYSTEMTIME st
string sz
GetLocalTime(&st)

' Day of month - d, dd
' Day of week  - ddd, dddd
' Month        - M, MM, MMM, MMMM
' Year         - y, yy, yyyy
GetDateFormatA(0, 0, &st, "yyyy.MM.dd", sz, 256) : print sz
GetDateFormatA(0, 0, &st, "MM/dd/200y", sz, 256) : print sz
GetDateFormatA(0, 0, &st, "ddd, MMM yyyy", sz, 256) : print sz
GetDateFormatA(0, 0, &st, "dddd, dd MMM yy", sz, 256) : print sz

__getch()

JoaoAfonso

My problem is how to get date from the calendar in DPI. The SENDMESSAGEA(dp,DTM_GETSYTEMTIME,0,mt) in checkdate(dp:uint),string routine should send to MT, a systemtime variable, all the information in the calendar (at least that is my intention), but the information sent seems random numbers. I am missing something.
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

sapero

Be sure you are passing the address of instead the first value of SYSTEMTIME structure. Not sure how EB, but Aurora when a parameter type is defined as INT and you pass here the name of UDT variable, the first value will be pushed - also it will be here the 'wYear' member.

Try with & operator:
SENDMESSAGEA(dp,DTM_GETSYTEMTIME,0, &mt)
BTW DTM_GETSYSTEMTIME

JoaoAfonso

Using &mt gives me the error of "no appropriate conversion exists".

Noticed already the GETSY(S)TEMTIME and fixed :)

Also noticed that using 2 calendars, one set to today and one set to tomorrow, results are the same (still not usable, still random numbers, but I was expecting eventually a difference of one from one day to other).
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

sapero

How did you declared SENDMESSAGEA? Maybe attach your project here, guessing is not my strong side.

JoaoAfonso

CONST DTM_GETSYSTEMTIME=&H1000 + 1
CONST DTM_SETSYSTEMTIME=&H1000 + 2
SETID "WS_VISIBLE",&H10000000
SETID "WS_CHILD",&H40000000
SETID "dpShortDate",&H0
SETID "dpLongDate",&H4
SETID "DP1",100
SETID "IDMOUSEWHEEL",522

TYPE SYSTEMTIME,2
DEF wYear:WORD
DEF wMonth:WORD
    DEF wDayOfWeek:WORD
    DEF wDay:WORD
    DEF wHour:WORD
    DEF wMinute:WORD
    DEF wSecond:WORD
    DEF wMilliseconds:WORD
ENDTYPE


DECLARE "kernel32",GetLocalTime(mt:SYSTEMTIME)
DECLARE "user32",SendMessageA(wnd:INT,message:INT,wparam:INT,st:SYSTIME),INT
DECLARE "user32",CreateWindowExA(ex:INT,classs:STRING,name:STRING,style:INT,x:INT,y:INT,nWidth:INT,nHeight:INT,hWndParent:UINT,ctrID:INT,hinstance:INT,lpParam:INT),UINT
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

sapero

I'm unable to find what's wrong with your code. Try with my next example, it should work:'$include "windows.inc"
'$include "commctrl.inc"
declare import, GetDateFormatA(int locale, int flags, pointer date, string format, string out, int outlen)
CONST DTM_GETSYSTEMTIME=0x1001
type SYSTEMTIME
WORD wYear: WORD wMonth: WORD wDayOfWeek: WORD wDay: WORD wHour: WORD wMinute: WORD wSecond: WORD wMilliseconds
endtype

CONST IDC_DATE = 1000
CONST IDC_READ = 1001
CONST IDC_TEXT = 1002

DIALOG d1
CREATEDIALOG d1,0,0,300,202,0x80CA0880,0,"Caption",&d1_handler
CONTROLEX d1,"SysDateTimePick32","Custom",29,11,150,20,0x50010004,0x0,IDC_DATE
CONTROL d1,@SYSBUTTON,"read date",184,11,70,20,0x50010000,IDC_READ
CONTROL d1,@EDIT,"",29,50,139,23,0x50810081,IDC_TEXT
domodal d1


SUB d1_handler
SYSTEMTIME st
string str

SELECT @MESSAGE
' case @IDINITDIALOG:
' goto check // date is read correctly
CASE @IDCLOSEWINDOW
CLOSEDIALOG d1,@IDOK

CASE @IDCONTROL
SELECT @WPARAM
CASE IDC_READ
'check:
if SendMessage(d1, DTM_GETSYSTEMTIME, 0, &st, IDC_DATE)
MessageBox @HITWINDOW, "DTM_GETSYSTEMTIME failed", ""
else
GetDateFormatA(0, 0, &st, "dd  MM  yyyy", str, 256)
SetControlText d1, IDC_TEXT, str
endif
ENDSELECT
ENDSELECT
RETURN
ENDSUB

JoaoAfonso

Excelent! With some adaptations, it is much more simple and easy than what I had before. Thank you, Sapero :)
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

JoaoAfonso

Something anoying is happening in my prog. If my controlex is of SysMonthCal32 type and when I click in the calendar, the routine runs 3 times.

This is how it's coded in the dialog handler

CASE @IDCONTROL
SELECT @CONTROLID
CASE 3
GOSUB rotina

where rotina sub is

SUB rotina
SYSTEMTIME st
STRING gdh
SENDMESSAGE(d12,DTM_GETSYSTEMTIME,0,&st,7)
GetDateFormatA(0, 0, &st, "ddMMMyy", gdh, 256):gdh=UCASE$(gdh)
MESSAGEBOX 0,gdh,"Ni"
ENDSUB


Each time I pick a different day, this messagebox shows 3 times. It is late here, but what am I doing wrong? How to avoid this?

Thanks in advance

JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

LarryMc

Not sure but try changing this:CASE @IDCONTROL
   SELECT @CONTROLID
      CASE 3
         GOSUB rotina


to this:

CASE @IDCONTROL
   SELECT @CONTROLID
      CASE 3
         IF @NOTIFYCODE = 0
            GOSUB rotina
         Endif

and see if it helps any.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

sapero

:) You should validate the @NOTIFYCODE variable for a DTN_ enumeration. The dtpicker might send DTN_DROPDOWN, DTN_DATETIMECHANGE and DTN_CLOSEUP, so you receive three notifications.

JoaoAfonso

Ok, couldn't check the values DTN_DROPDOWN, DATETIMECHANGE and CLOSEUP consts should have, but checking for @notifycode results with messagebox, I did the following which works, but still have doubt if in anyother computer will work this way:

CONST DTN_CLOSEUP = -746

and

CASE 3
IF @NOTIFYCODE = DTN_CLOSEUP THEN GOSUB rotina


So using messagebox to print @notifycodes, got 3 different values. Used the last one, the -746, which should be the dtn_closeup. Again it works now, but dunno if in every computer. If someone can assure me I am thinking correctly, I would be glad. Thank you for the tips :)
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900