[Solved] Can't get MCM_SETDAYSTATE for calendar control to work??

Started by hotrod, November 20, 2009, 10:24:46 PM

Previous topic - Next topic

hotrod

I tried this and a few other things, but can't get it to work; does anyone have a sample?  Thanks,
mov eax, 01111b
mov days, eax
invoke SendMessage,hIDC_MVI1,MCM_SETDAYSTATE,4,addr days

jj2007


hotrod

I have the SDK and I have worked on this for the entire day passing all kinds of arrays in differenct amounts. According to the SDK, MCM_SETDAYSTATE is looking for a binary value
QuoteThe MONTHDAYSTATE data type is a bit field that holds the state of each day in a month. The data type is defined in Commctrl.h as follows:

typedef DWORD MONTHDAYSTATE, *LPMONTHDAYSTATE;
Each bit (1 through 31) represents the state of a day in a month. If a bit is on, the corresponding day will be displayed in bold; otherwise it will be displayed with no emphasis.

This data type is used with the MCM_SETDAYSTATE message and the corresponding macro, MonthCal_SetDayState. When MONTHDAYSTATE values are used in reference to months shorter than 31 days, only the needed bits will be accessed.

This data type was first defined in Version 4.70 of Comctl32.dll.
I have also trieddays dd 1,2,3,4 etc...

jj2007

Ok. You need a MONTHDAYSTATE bit field holding 31 bits. Since you have not posted a complete example, I cannot test it, but I would try this:

.data
days dd 01010b, 01111b, 010b, 010b  ; whatever - 4 dwords with 32 bits each

.code
invoke SendMessage, hIDC_MVI1, MCM_SETDAYSTATE, 4, offset days


Unfortunately, Bill Cravener's calendar in \masm32\examples\bcraven\calender\calendar.asm does not use this message... although it is worth studying.

hotrod

ok, here is the entire code of concern starting with the .asm:
.386
.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive

include testcal.inc

.code

start:

invoke GetModuleHandle,NULL
mov hInstance,eax

    invoke InitCommonControls
invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL
invoke ExitProcess,0
DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

mov eax,uMsg
.if eax==WM_INITDIALOG
invoke GetDlgItem,hWin,IDC_MVI1
mov hIDC_MVI1,eax
invoke SendMessage,hIDC_MVI1,MCM_SETMONTHDELTA,1,0 ; Set number of months calendar scrolls
.elseif eax==WM_COMMAND
mov eax, wParam
.if eax==1002
invoke SendMessage,hIDC_MVI1,MCM_SETDAYSTATE,4,addr days
.endif
.elseif eax==WM_CLOSE
invoke EndDialog,hWin,0
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
end start


Now the .inc
include windows.inc
include kernel32.inc
include user32.inc
include Comctl32.inc
include shell32.inc

includelib kernel32.lib
includelib user32.lib
includelib Comctl32.lib
includelib shell32.lib

DlgProc PROTO :HWND,:UINT,:WPARAM,:LPARAM

.const
IDD_DIALOG1 equ 101
IDC_MVI1 equ 1001
IDC_BTN1 equ 1002

.data
days dd 01010b, 01111b, 010b, 010b  ; whatever - 4 dwords with 32 bits each

.data?
hInstance dd ?
hIDC_MVI1 HWND ?

and last is the .rc
#define IDD_DIALOG1 101
#define IDC_MVI1 1001
#define IDC_BTN1 1002
IDD_DIALOG1 DIALOGEX 6,6,263,183
FONT 8,"MS Sans Serif",0,0
STYLE 0x10CF0800
EXSTYLE 0x00000000
BEGIN
  CONTROL "",IDC_MVI1,"SysMonthCal32",0x50000000,1,3,257,97,0x00000200
  CONTROL "Set day state",IDC_BTN1,"Button",0x50010000,8,110,48,17,0x00000000
END

jj2007

Bueno. Attached a "formatted" version of your code, in case someone else is interested.
It definitely looks cute, but Microsoft has bad news:

Thank you for using Microsoft Managed Newsgroup Service, I'm Zhi-Xin Ye,
it's my pleasure to work with you on this issue.

As I understand, you want to bold some dates in the MonthCalendar part of
the DateTimePicker.

To bold a particular date you need to send the underlying SysMonthCal32
control the MCM_SETDAYSTATE message where each bit represents a day of the
month.  However, this message is really tough to handle in this scenario,
as you might have tried lots of P/Invoke approaches.

After doing some reseach on this issue, I find a managed way to bold the
dates which avoids the Win32 stuff.  The trick is placing a MonthCalendar
inside a ToolStripControlHost, and show it right upon the DateTimePicker's
MonthCalendar. Through this approach you can using the
MonthCalendar.BoldedDates, MonthCalendar.MonthlyBoldedDates and
AnnuallyBoldedDates properties to bold whatever dates you like.


Isn't that woohaha...? :cheekygreen:
But in Masm32 we never give up. Victory over M$ is just postponed :bg

hotrod

jj2007, what OS are you running, it still doesn't work on XP Pro SP3. I checked with SDK and it says:
QuoteMinimum operating systems Windows 2000, Windows NT 4.0 with Internet Explorer 3.0, Windows 98, Windows 95 with Internet Explorer 3.0
but this isn't always true when M$ is envolved.

jj2007

My OS is XP SP2, but it won't work. Google says many people have problems with it...

hotrod

ULK! Someone has got to have the answer - Hutch, anyone??? Hello!!!!

jj2007

You are an optimist. If a Microsoft employee writes "a managed way to bold the dates which avoids the Win32 stuff.  The trick is placing a MonthCalendar inside a ToolStripControlHost", then it means you need a Kalachnikov to kill this fly. I would try to google for a working example, in any language...

MichaelW

The attachment is a small working example built as a MASM32 in-memory dialog.
eschew obfuscation

hotrod

MichaelW, I want to thank you very much; I had no idea about how to do this considering what your working example looks like. I had seen some examples in other languages that would take a week to decode and not even knowing if they worked. You have my humble appreciation.

jj2007

    DlgMonthCal MCS_DAYSTATE or MCS_NOTODAYCIRCLE,0,0,118,100,101

Michael is the greatest :wink