Outlook calendar gadget ...???

Just starting out? Need help? Post your questions and find answers here.
LuckyLuke
Enthusiast
Enthusiast
Posts: 181
Joined: Fri Jun 06, 2003 2:41 pm
Location: Belgium

Outlook calendar gadget ...???

Post by LuckyLuke »

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.

LuckyLuke
localmotion34
Enthusiast
Enthusiast
Posts: 665
Joined: Fri Sep 12, 2003 10:40 pm
Location: Tallahassee, Florida

Post by localmotion34 »

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.

Code: Select all

!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
Tommeh
Enthusiast
Enthusiast
Posts: 149
Joined: Sun Aug 29, 2004 2:25 pm
Location: United Kingdom

Post by Tommeh »

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

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

va!n
Addict
Addict
Posts: 1104
Joined: Wed Apr 20, 2005 12:48 pm

Post by va!n »

i did not checked the code yet... just saw the result and i must say: fine !!!
va!n aka Thorsten

Intel i7-980X Extreme Edition, 12 GB DDR3, Radeon 5870 2GB, Windows7 x64,
localmotion34
Enthusiast
Enthusiast
Posts: 665
Joined: Fri Sep 12, 2003 10:40 pm
Location: Tallahassee, Florida

Post by localmotion34 »

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.

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)
trust me, one false move with a linked list and all your variable info in the structure is wrong, and craaaash.

Code: Select all

!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
Tommeh
Enthusiast
Enthusiast
Posts: 149
Joined: Sun Aug 29, 2004 2:25 pm
Location: United Kingdom

Post by Tommeh »

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

Code: Select all

          Cad()\Object[Cad()\CurrentEdit]\Point[Cad()\Object[Cad()\CurrentEdit]\LastPoint]\Type     = "l"
But it does seem to work everytime and pretty good about resource usage :D

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 :)
LuckyLuke
Enthusiast
Enthusiast
Posts: 181
Joined: Fri Jun 06, 2003 2:41 pm
Location: Belgium

Post by LuckyLuke »

Very cool ! Thanks a lot !
I'll study the code this weekend. Very interesting.

@Tommeh : feel free to add task ans stuff to it (day view ?) ... very much appreciated. :D

Maybe this control can be added in the next version of PureBasic ?

LuckyLuke
LuckyLuke
Enthusiast
Enthusiast
Posts: 181
Joined: Fri Jun 06, 2003 2:41 pm
Location: Belgium

Post by LuckyLuke »

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.

LuckyLuke
Post Reply