I'm thinking of using Purebasic for my next project, however I need an
outllook calendar (month and day view) gadget. Drag and drop should also be possible for the planned tasks.
Any ideas ?
Thanks.
Outlook calendar gadget ...???
Outlook calendar gadget ...???
LuckyLuke
-
- Enthusiast
- Posts: 665
- Joined: Fri Sep 12, 2003 10:40 pm
- Location: Tallahassee, Florida
Look at all my examples of SUBCLASSING, i.e. the listbox code, the ownerdraw combobox, the LED gadget, the meter control...
Become very familiar with how those work, all the drawing, the message processing ect. especially look at my custom messages to the meter control. Check out my Powerpoint Listview and DirectUI Hwnd examples as a perfect example of using a custom gadgets and integrating them into the event loop.
then you can create a gadget, and decide how it will operate.
you need to process, #wm_paint, #wm_lbuttondown ect.
you might also want messages like #pb_outlook_update to tell the calendar to update its content after a user changes some text.
This is not a small task.
Become very familiar with how those work, all the drawing, the message processing ect. especially look at my custom messages to the meter control. Check out my Powerpoint Listview and DirectUI Hwnd examples as a perfect example of using a custom gadgets and integrating them into the event loop.
then you can create a gadget, and decide how it will operate.
you need to process, #wm_paint, #wm_lbuttondown ect.
you might also want messages like #pb_outlook_update to tell the calendar to update its content after a user changes some text.
This is not a small task.
Code: Select all
!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
Things like drop and drag for tasks will be quiet a big task
Anyhow, this is one of the many side projects i've been doing (I get easily distracted), i saw this post so i thought i might as well quickly fix it up and let you see if its any good to you
I love doing gadgets i find it really fun, I've done this, a Gallery gadget, Graph gadget, and most complex so far im working on is a CAD gadget with drop and drag ;)
The gadget is dynamically sized to the size you ask the gadget, that is the boxes will take up more or less room depending on the size of the gadget (Leaving space for the possibility of an extra row) but no resize gadget command has been implemented yet.
From this it would be quiet easy to add in tasks under the current date (Although my code is probibly really hard to read)
Anyway, any feedback's apprechiated
Anyhow, this is one of the many side projects i've been doing (I get easily distracted), i saw this post so i thought i might as well quickly fix it up and let you see if its any good to you
I love doing gadgets i find it really fun, I've done this, a Gallery gadget, Graph gadget, and most complex so far im working on is a CAD gadget with drop and drag ;)
The gadget is dynamically sized to the size you ask the gadget, that is the boxes will take up more or less room depending on the size of the gadget (Leaving space for the possibility of an extra row) but no resize gadget command has been implemented yet.
From this it would be quiet easy to add in tasks under the current date (Although my code is probibly really hard to read)
Anyway, any feedback's apprechiated
Code: Select all
;- Structures
Structure CalendarBoxInfo
BoxID.l
PosX.l
PosY.l
Width.l
Height.l
RegionX1.l
RegionX2.l
RegionY1.l
RegionY2.l
IsActive.l
EndStructure
Structure CalendarGadgetInfo
GadgetID.l
WindowID.l
ImageID.l
ImgGadID.l
PosX.l
PosY.l
Width.l
Height.l
CurrentDate.l
Box.CalendarBoxInfo[100]
EndStructure
;- Error Messages
#CALENDARERROR_PRVINIT = 1
#CALENDARERROR_NODRAW = 2
#CALENDARERROR_NOIMGGAD = 3
#CALENDARERROR_NOCREATEIMG = 4
#CALENDARERROR_GADGETNOTFOUND = 5
;- Declares
Declare Calendar_CreateGadget(GadgetID, ParentID, x, y, Width, Height)
Declare Calendar_DrawGadget(GadgetID, MouseOver)
Global NewList Calendar.CalendarGadgetInfo()
Global TitleFont = LoadFont(#PB_Any, "Verdana", 14, #PB_Font_Bold)
Global DateFont = LoadFont(#PB_Any, "Arial", 8)
Procedure.s Calendar_GetError(ERROR_MSG)
Select ERROR_MSG
Case #CALENDARERROR_PRVINIT
RETURN_MSG$ = "There is already a gadget with that ID!"
Case #CALENDARERROR_NODRAW
RETURN_MSG$ = "Can not start drawing!"
Case #CALENDARERROR_NOIMGGAD
RETURN_MSG$ = "Can not create image gadget!"
Case #CALENDARERROR_NOCREATEIMG
RETURN_MSG$ = "Can not create image!"
Case #CALENDARERROR_GADGETNOTFOUND
RETURN_MSG$ = "GadgetID not found as a valid calendar gadget!"
Default
RETURN_MSG$ = "An unknown error has occoured!"
EndSelect
ProcedureReturn RETURN_MSG$
EndProcedure
Procedure Calendar_SubClass(hwnd,msg,wParam,lParam)
Select msg
Case #WM_MOUSEMOVE, #WM_MOUSELEAVE, #WM_NCMOUSEMOVE
ResetList(Calendar())
ForEach Calendar()
If GadgetID(Calendar()\ImgGadID) = hwnd
Break
Else
Goto Calendar_SubClassEND
EndIf
Next
MousePosX = WindowMouseX(Calendar()\WindowID) - Calendar()\PosX - 2
MousePosY = WindowMouseY(Calendar()\WindowID) - Calendar()\PosY - 2
For t = 1 To 42
If MousePosX > Calendar()\Box[t]\RegionX1 And MousePosX < Calendar()\Box[t]\RegionX2 And MousePosY > Calendar()\Box[t]\RegionY1 And MousePosY < Calendar()\Box[t]\RegionY2
Calendar()\Box[t]\IsActive = 1
If StartDrawing(ImageOutput(Calendar()\ImageID))
Calendar_DrawGadget(Calendar()\GadgetID, t)
StopDrawing()
SetGadgetState(Calendar()\ImgGadID, ImageID(Calendar()\ImageID))
EndIf
RedrawnPASS = 1
Break
EndIf
Next t
If RedrawnPASS = 0
If StartDrawing(ImageOutput(Calendar()\ImageID))
Calendar_DrawGadget(Calendar()\GadgetID, 0)
StopDrawing()
SetGadgetState(Calendar()\ImgGadID, ImageID(Calendar()\ImageID))
EndIf
EndIf
Case #WM_LBUTTONDOWN
ResetList(Calendar())
ForEach Calendar()
If GadgetID(Calendar()\ImgGadID) = hwnd
Break
Else
Goto Calendar_SubClassEND
EndIf
Next
MousePosX = WindowMouseX(Calendar()\WindowID) - Calendar()\PosX - 2
MousePosY = WindowMouseY(Calendar()\WindowID) - Calendar()\PosY - 2
If MousePosX > 13 And MousePosX < 96 And MousePosY > 13 And MousePosY < 36
Calendar()\CurrentDate = AddDate(Calendar()\CurrentDate, #PB_Date_Month, -1)
If StartDrawing(ImageOutput(Calendar()\ImageID))
Calendar_DrawGadget(Calendar()\GadgetID, t)
StopDrawing()
SetGadgetState(Calendar()\ImgGadID, ImageID(Calendar()\ImageID))
EndIf
EndIf
If MousePosX > Calendar()\Width - 102 And MousePosX < Calendar()\Width - 19 And MousePosY > 13 And MousePosY < 36
Calendar()\CurrentDate = AddDate(Calendar()\CurrentDate, #PB_Date_Month, 1)
If StartDrawing(ImageOutput(Calendar()\ImageID))
Calendar_DrawGadget(Calendar()\GadgetID, t)
StopDrawing()
SetGadgetState(Calendar()\ImgGadID, ImageID(Calendar()\ImageID))
EndIf
EndIf
If RedrawnPASS = 0
If StartDrawing(ImageOutput(Calendar()\ImageID))
Calendar_DrawGadget(Calendar()\GadgetID, 0)
StopDrawing()
SetGadgetState(Calendar()\ImgGadID, ImageID(Calendar()\ImageID))
EndIf
EndIf
Calendar_SubClassEND:
ProcedureReturn 0
EndSelect
ProcedureReturn CallWindowProc_(GetProp_(hwnd,"OldProc4"),hwnd,msg,wParam,lParam)
EndProcedure
Procedure.s MonthName(CurDate)
Select CurDate
Case 0
MonthReturn$ = "December"
Case 1
MonthReturn$ = "January"
Case 2
MonthReturn$ = "Feburary"
Case 3
MonthReturn$ = "March"
Case 4
MonthReturn$ = "April"
Case 5
MonthReturn$ = "May"
Case 6
MonthReturn$ = "June"
Case 7
MonthReturn$ = "July"
Case 8
MonthReturn$ = "August"
Case 9
MonthReturn$ = "September"
Case 10
MonthReturn$ = "October"
Case 11
MonthReturn$ = "November"
Case 12
MonthReturn$ = "December"
Case 13
MonthReturn$ = "January"
Default
MonthReturn$ = "Error finding month value!"
EndSelect
ProcedureReturn MonthReturn$
EndProcedure
Procedure.s DayName(CurDay)
Select CurDay
Case 0, 7, 14, 21, 28, 35, 42
DayReturn$ = "Sunday"
Case 1, 8, 15, 22, 29, 36
DayReturn$ = "Monday"
Case 2, 9, 16, 23, 30, 37
DayReturn$ = "Tuesday"
Case 3, 10, 17, 24, 31, 38
DayReturn$ = "Wednesday"
Case 4, 11, 18, 25, 32, 39
DayReturn$ = "Thursday"
Case 5, 12, 19, 26, 33, 40
DayReturn$ = "Friday"
Case 6, 13, 20, 27, 34, 41
DayReturn$ = "Saturday"
Default
DayReturn$ = "Error finding day value!"
EndSelect
ProcedureReturn DayReturn$
EndProcedure
Procedure GetLastDay(CurDate)
For t = 26 To 32;heh just incase they invent some weird new system ;)
If ParseDate("%dd/%mm/%yyyy", Str(t)+"/"+Str(Month(CurDate))+"/"+Str(Year(CurDate))) > 0
Lastdayofmonth = t
Else
Break
EndIf
Next t
ProcedureReturn Lastdayofmonth
EndProcedure
Procedure Calendar_DrawGadget(GadgetID, MouseOver)
ResetList(Calendar())
ForEach Calendar()
If Calendar()\GadgetID = GadgetID
Goto Calendar_DrawSTART
EndIf
Next
ERROR_MSG = #CALENDARERROR_GADGETNOTFOUND
Debug Calendar_GetError(ERROR_MSG)
Goto Calendar_DrawEND
Calendar_DrawSTART:
Box(0, 0, Calendar()\Width, Calendar()\Height, RGB(255,255,255))
Box(10, 10, Calendar()\Width - 20, 30, RGB($B0,$D5,$EF))
Box(15, 15, 80, 20, RGB(193, 184, 207))
Box(Calendar()\Width - 100, 15, 80, 20, RGB(193, 184, 207))
CurrentMonth$ = MonthName(Month(Calendar()\CurrentDate))
CurrentYear$ = Str(Year(Calendar()\CurrentDate))
CurrentDisplay$ = CurrentMonth$ + " - " + CurrentYear$
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(55 - (TextWidth(MonthName(Month(Calendar()\CurrentDate)-1))/ 2), 15, MonthName(Month(Calendar()\CurrentDate)-1))
DrawText((Calendar()\Width - 60) - (TextWidth(MonthName(Month(Calendar()\CurrentDate)+1))/ 2), 15, MonthName(Month(Calendar()\CurrentDate)+1))
DrawingFont(FontID(TitleFont))
DrawText((Calendar()\Width / 2) - (TextWidth(CurrentDisplay$) / 2), 15, CurrentDisplay$)
DrawingMode(#PB_2DDrawing_Outlined)
Box(14, 14, 82, 22, RGB(0, 0, 0))
Box(Calendar()\Width - 101, 14, 82, 22, RGB(0, 0, 0))
DrawingFont(FontID(DateFont))
FirstdayDone = 0
Firstday = DayOfWeek(ParseDate("%dd/%mm/%yyyy", "01/" + Str(Month(Calendar()\CurrentDate)) + "/" + Str(Year(Calendar()\CurrentDate))))
LastDay = GetLastDay(Calendar()\CurrentDate)
z = 0 : Daynumber = 0
For y = 1 To 6
For x = 1 To 7
z + 1
If (DayName(z-1) = DayName(Firstday) Or FirstdayDone = 1) And z < LastDay + Firstday + 1
FirstdayDone = 1
Daynumber + 1
DrawingMode(#PB_2DDrawing_Outlined)
Calendar()\Box[z]\BoxID = z
Calendar()\Box[z]\RegionX1 = (Calendar()\Width / 7.5) * (x-0.75)
Calendar()\Box[z]\RegionY1 = (Calendar()\Height / 6.8) * (y-0.2)
Calendar()\Box[z]\RegionX2 = (Calendar()\Box[z]\RegionX1) + (Calendar()\Width * 0.12)
Calendar()\Box[z]\RegionY2 = (Calendar()\Box[z]\RegionY1) + (Calendar()\Height * 0.13)
If MouseOver = z
CalendarBoxColor = RGB(0, 0, 0)
Else
CalendarBoxColor = RGB($9D,$AA,$FF)
EndIf
Box((Calendar()\Width / 7.5) * (x-0.75), (Calendar()\Height / 6.8) * (y-0.2), Calendar()\Width * 0.12, Calendar()\Height * 0.13, CalendarBoxColor)
Box(((Calendar()\Width / 7.5) * (x-0.75))+1, ((Calendar()\Height / 6.8) * (y-0.2))+1, (Calendar()\Width * 0.12)-2, (Calendar()\Height * 0.13)-2, RGB($82,$92,$FF))
DrawingMode(0)
Box(Calendar()\Box[z]\RegionX2-22, Calendar()\Box[z]\RegionY1+2, 20, 20, RGB($5B,$60,$F9))
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(Calendar()\Box[z]\RegionX2-20, Calendar()\Box[z]\RegionY1+4, RSet(Str(Daynumber), 2, " "))
DrawText(Calendar()\Box[z]\RegionX1+5, Calendar()\Box[z]\RegionY1+5, DayName(z-1))
EndIf
Next x
Next y
Calendar_DrawEND:
ProcedureReturn 0
EndProcedure
Procedure Calendar_CreateGadget(GadgetID, ParentID, x, y, Width, Height)
ResetList(Calendar())
ForEach Calendar()
If Calendar()\GadgetID = GadgetID
ERROR_MSG = #CALENDARERROR_PRVINIT
Debug Calendar_GetError(ERROR_MSG)
Goto Calendar_CreateEND
EndIf
Next
AddElement(Calendar())
Calendar()\GadgetID = GadgetID
Calendar()\WindowID = ParentID
Calendar()\PosX = x
Calendar()\PosY = y
Calendar()\Width = Width
Calendar()\Height = Height
Calendar()\CurrentDate = Date()
Calendar_CreateSTART:
Calendar()\ImageID = CreateImage(#PB_Any, Calendar()\Width, Calendar()\Height)
If Calendar()\ImageID
If StartDrawing(ImageOutput(Calendar()\ImageID))
Calendar_DrawGadget(Calendar()\GadgetID, 0)
StopDrawing()
Calendar()\ImgGadID = ImageGadget(#PB_Any, Calendar()\PosX, Calendar()\PosY, Calendar()\Width, Calendar()\Height, ImageID(Calendar()\ImageID), #PB_Image_Border)
SetGadgetState(Calendar()\ImgGadID, ImageID(Calendar()\ImageID))
Calendar_CreateReturn = Calendar()\GadgetID
SetParent_(GadgetID(Calendar()\ImgGadID),WindowID(Calendar()\WindowID))
oldstyle=GetWindowLong_(GadgetID(Calendar()\ImgGadID),#GWL_STYLE)
SetWindowLong_(GadgetID(Calendar()\ImgGadID),#GWL_STYLE,oldstyle|#SS_ICON)
RedrawWindow_(WindowID(Calendar()\WindowID),0,0,#RDW_ALLCHILDREN)
SetProp_(GadgetID(Calendar()\ImgGadID),"OldProc4",SetWindowLong_(GadgetID(Calendar()\ImgGadID), #GWL_WNDPROC, @Calendar_SubClass()))
EndIf
Else
ERROR_MSG = #CALENDARERROR_NODRAW
Debug Calendar_GetError(ERROR_MSG)
Goto Calendar_CreateEND
EndIf
Calendar_CreateEND:
ProcedureReturn Calendar_CreateReturn
EndProcedure
WinID = OpenWindow(1, 50, 50, 825, 600, "Tommeh's Calendar Gadget :: Test")
CreateGadgetList(WinID)
Calendar_CreateGadget(1, 1, 10, 10, 800, 580)
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
-
- Enthusiast
- Posts: 665
- Joined: Fri Sep 12, 2003 10:40 pm
- Location: Tallahassee, Florida
great code!!
however, using linked lists is NOT the best and most error free way to do it.
if youll look back at my old codes i use linked lists, and then some newer ones, i ALWAYS use a structured variable and store that as a property with SetProp_().
that way, your gadget info is ALWAYS stored with your gadget hwnd.
trust me, one false move with a linked list and all your variable info in the structure is wrong, and craaaash.
however, using linked lists is NOT the best and most error free way to do it.
if youll look back at my old codes i use linked lists, and then some newer ones, i ALWAYS use a structured variable and store that as a property with SetProp_().
that way, your gadget info is ALWAYS stored with your gadget hwnd.
Code: Select all
Structure CalendarBoxInfo
BoxID.l
PosX.l
PosY.l
Width.l
Height.l
RegionX1.l
RegionX2.l
RegionY1.l
RegionY2.l
IsActive.l
EndStructure
Structure CalendarGadgetInfo
GadgetID.l
WindowID.l
ImageID.l
ImgGadID.l
PosX.l
PosY.l
Width.l
Height.l
CurrentDate.l
Box.CalendarBoxInfo[100]
EndStructure
*gadget.calendargadgetifo=allocatememory(sizeof(calendargadgetinfo))
;;;set your values here
setprop_(gadgetid(calendar),"info",*gadget.calendargadgetifo)
Code: Select all
!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
The only problem then, is handling multiple gadgets, with the code posted above you can have many gadgets, per many windows. I kind of see what your saying, it takes a lot of time and patience with linked lists to make sure you get it right and can get very complicated
For example with my cad gadget, its got 3 nested linked lists to handle the amount of data it has to and you end up with some code like
But it does seem to work everytime and pretty good about resource usage 
PS, I have to go to work now but when i get back if people want it ill add it so you can add tasks and stuff to it
Also seems having 2 gadgets dosnt quiet work right as there is a bug in the subclass routine will fix later
For example with my cad gadget, its got 3 nested linked lists to handle the amount of data it has to and you end up with some code like
Code: Select all
Cad()\Object[Cad()\CurrentEdit]\Point[Cad()\Object[Cad()\CurrentEdit]\LastPoint]\Type = "l"

PS, I have to go to work now but when i get back if people want it ill add it so you can add tasks and stuff to it

Also seems having 2 gadgets dosnt quiet work right as there is a bug in the subclass routine will fix later

Found a sample in c#
http://www.codeproject.com/cs/miscctrl/ ... ayview.asp
They are using a stringgadget for the events.
If someone can use this and convert it to PB ?
Thx.
http://www.codeproject.com/cs/miscctrl/ ... ayview.asp
They are using a stringgadget for the events.
If someone can use this and convert it to PB ?
Thx.
LuckyLuke