|
My List View class is constructed according to
Michael Dunn ritual as follows:
typedef CCheckListViewCtrlImplTraits
<0,0,LVS_EX_CHECKBOXES|LVS_EX_GRIDLINES|LVS_EX_UNDERLINEHOT|
LVS_EX_ONECLICKACTIVATE|LVS_EX_FLATSB|LVS_OWNERDATA> CMyCheckListTraits;
class CMyListView:
public CCheckListViewCtrlImpl<CMyListView,CListViewCtrl,CMyCheckListTraits>
{
.......
};
so the style LVS_OWNERDATA is somehow inhereted.
Adding of the line
SetExtendedListViewStyle(GetExtendedListViewStyle()|LVS_OWNERDATA);
to the List View's OnCreate()
gives no results as well.
Replacing elaborate Michael Dunn's class with plain and simple
class CMyListView: public CWindowImpl<CMyListView,CListViewCtrl>
produced by WTL Wizard gives no effect as well.
Missing "EX" in the name LVS_OWNERDATA makes it plausible,
that CListView has another kind of style, different from "extended" one.
Looking through atlctrls.h I've seen no counterparts of
Get|SetExtendedListViewStyle() without "Extended".
But there is a function Create() having both kinds of style as parameters.
But adding
ATL::CWindow parent=GetParent();
Create(parent.m_hWnd,0,0,LVS_OWNERDATA,
LVS_EX_CHECKBOXES|LVS_EX_GRIDLINES|LVS_EX_UNDERLINEHOT|
LVS_EX_ONECLICKACTIVATE|LVS_EX_FLATSB);
to OnCreate() compiles OK, but leads to the crash of the prog at sturtup.
And the debugger says that ListView has no parent: parent.m_hWnd==0.
Replacing of GetParent() with GetTopLevelWindow() produces the same result.
So, I do not know at present, how one can correctly set this style at all.
|
|
|
|
|
Try using this as the traits style
typedef CCheckListViewCtrlImplTraits<WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS|LVS_OWNERDATA, WS_EX_CLIENTEDGE, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT> CCheckListViewCtrlTraits;
This applies LVS_OWNERDATA as a basic window style.
|
|
|
|
|
Yes, I guessed, looking at the code in atlctrlx.h,
that LVS_OWNERDATA belongs to the same kind of style
as all WS_XXX styles, so placed it in the first template
parameter. But this produced no effect -- no notifications
LVN_ODSTATECHANGED or LVN_SETDISPINFO were triggered by the app.
In fact the class CCheckListViewCtrlImplTraits<...>
has no member fields, it only defines three member functions
GetWndStyle(DWORD dwStyle), GetWndExStyle(DWORD dwExStyle) and
GetExtendedLVStyle(). The first 2 of them IGNORE first 2 template
parameters if being called with non-zero style argument.
So it seems that if these 2 functions were called at all,
say, by CListView constructor, they were called with non-zero
argument (default style for List View), so these 2 template parameters were ignored and CListView was constructed with some set of default style arguments, not including LVS_OWNERDATA.
I tried to modify the style "manually",
adding the line
ModifyStyle(0,GetWndStyle(0),0);
to OnCreate(), but this again produced no effect.
-- modified at 11:18 Wednesday 13th June, 2007
|
|
|
|
|
OK - I knocked up a quick sample using splitters and list views.
1. Creating the list view (and a rich edit control) as children of a splitter - this is part of CMainFrame::OnCreate :
splitter_.Create(*this, rcDefault, 0, 0, WS_EX_CLIENTEDGE);
list_.Create(splitter_, rcDefault, 0, CControlWinTraits::GetWndStyle(0)|LVS_OWNERDATA|LVS_REPORT, CControlWinTraits::GetWndExStyle(0), 1234, 0);
edit_.Create(splitter_, rcDefault, 0,
WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_READONLY|ES_AUTOHSCROLL|ES_AUTOVSCROLL|ES_MULTILINE);
edit_.SetFont(AtlGetStockFont(ANSI_FIXED_FONT));
m_hWndClient = splitter_;
splitter_.SetSplitterPanes(list_, edit_);
list_.AddColumn(_T("Test"), 0);
list_.SetItemCount(20);
UpdateLayout();
splitter_.SetSplitterPos(200);
The controls are declared as members of CMainFrame with these types:
CSplitterWindow splitter_;
CListViewCtrl list_;
CRichEditCtrl edit_;
Note that LVS_OWNERDATA is part of the window style (i.e. ORed with styles like WS_VISIBLE etc). SetItemCount tells the list view what items to ask for.
2. I handle notifications like this:
MainFrm.h: (this is within the CMainFrame definition)
BEGIN_MSG_MAP(CMainFrame)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew)
COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
NOTIFY_HANDLER(1234, LVN_GETDISPINFO, OnGetDispInfo)
NOTIFY_HANDLER(1234, LVN_ODSTATECHANGED, OnODStateChanged)
CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
END_MSG_MAP()
LRESULT OnGetDispInfo(WORD , LPNMHDR nmHeader, BOOL&);
LRESULT OnODStateChanged(WORD , LPNMHDR nmHeader, BOOL&);
MainFrm.cpp:
LRESULT CMainFrame::OnGetDispInfo(WORD , LPNMHDR nmHeader, BOOL&)
{
NMLVDISPINFO* getDispInfo = reinterpret_cast<NMLVDISPINFO*>(nmHeader);
getDispInfo->item.state = LVIF_TEXT;
CString s;
s.Format(_T("%d"), getDispInfo->item.iItem);
lstrcpy(getDispInfo->item.pszText, s);
return 0;
}
LRESULT CMainFrame::OnODStateChanged(WORD , LPNMHDR nmHeader, BOOL&)
{
OutputDebugString(_T("CMainFrame::OnODStateChanged"));
return 0;
}
LVN_ODSTATECHANGED is fired by the list view when you do a Shift-click to select multiple items. LVN_ITEMCHANGED seems to be fired when single items are selected.
Anyway - hope this helps.
|
|
|
|
|
1. The immediate child windows of the splitter in my app
are 2 CPaneContainers (their function is just to show
text labels). ListView and RichEdit controls are childs
of these Pane containers. I think this is not essential
difference with Your sample. Except the eventual cases
when I will need the "real" parent of List View -- CMainFrame
and not CPaneContainer -- I should call GetParent() twice.
2. And what is very essential difference, surely responsible
for the bug in my app is that I choose wrong format
for notification handlers. I mimicked the definition
of the message handler for LVN_ITEMCHANGED:
NOTIFY_CODE_HANDLER_EX(LVN_ITEMCHANGED, OnLvnItemChanged)
Now I see from Your example that the correct format
for LVN_ODSTATECHANGED and LVN_GETDISPINFO
must use the macro NOTIFY_HANDLER(...) instead!
OK, now I'll rewrite my code in accord with Your sample code.
Hope this really would help.
Thank You very much in advance!
...Well I've modified my code. Really, my app now triggers
messages if shift+Mouse is clicked. But:
1) After several such clicks app crashes due to variety
of reasons. One of them is out of memory error.
These bugs probably can be fixed,
but this may take too much time;
2) Check boxes do not appear. If one or's the item state flag
with LVIF_IMAGE an empty place appears before messages instead of
checkboxes.
3) List view items info, set by ListView.InsertItem(i,text)
is ignored:
if one comments the line:
lstrcpy(getDispInfo->item.pszText, s);
in OnGetDispInfo() the texts of all items becomes empty.
This is not fatal, because I can set item texts
in OnGetDispInfo() calling InsertItem with empty text=L"";
4) Most important of all: there are no notifications
in case of ctrl+click as well as in case of simple clicks.
Using of LVN_ITEMCHANGED together with LVN_ODSTATECHANGED
does not resolve the problem of multiple LVN_ITEMCHANGED
events (see posts above), creating an additional mess.
By the way, even a single mouse click (with no shift or ctrl)
can clearly change the state of many items at once
creating multiple LVN_ITEMCHANGED events.
-- modified at 13:17 Wednesday 13th June, 2007
|
|
|
|
|
I have a TCPIP server using the fonction recv(). The header contain the sise of message. Then I read the entire message.
I would like have a dynamic buffer char* because the server get many different size of data from 10 until 30000 char, but 80% from message are shorter as 100 char.
I have test the following code but it's do not works, I do not understand why.
'msglenght'
char* msgBuffer;
msgBuffer=(char*)malloc( msglenght );
memset(msgBuffer,0,msglenght);
rVal = recv(m_acceptSocket,msgBuffer,msglenght,0);
when I show the contain of msgBuffer it is empty.
Thank you for help
AutreChien
|
|
|
|
|
That should work - I use the exact same call in a program using sockets I wrote recently. How many bytes is recv getting (that's the return value from recv )?
|
|
|
|
|
I'm having a problem dereferencing a function pointer in a std:map,
and actually getting it to run the function. I'm fairly clueless on
this sort of thing, but I know there is a way to make it work.
Ideas?
Given the following setup:
typedef void(CMyClass::*Func_Ptr)(void);<br />
typedef std::map<int, Func_Ptr> CommandFunctionMap;<br />
CommandFunctionMap g_cmdfuncts;<br />
<br />
Add some function pointers:<br />
<br />
g_cmdfuncts.insert( std::pair<int, Func_Ptr>(CMDADOA, CmdADoA) );<br />
g_cmdfuncts.insert( std::pair<int, Func_Ptr>(CMDADOB, CmdADoB) );<br />
g_cmdfuncts.insert( std::pair<int, Func_Ptr>(CMDADOC, CmdADoC) ); <br />
<br />
<br />
Now, find the right command in the map:<br />
<br />
Func_Ptr fp;<br />
int command = CMDADOA;<br />
CommandFunctionMap::iterator commandIter;<br />
<br />
commandIter = g_cmdfuncts.find(command);<br />
if( commandIter != g_cmdfuncts.end() )<br />
{<br />
fp = (*commandIter).second;<br />
fp;
}<br />
|
|
|
|
|
[Edit - Sorry - I didn't notice it was a method function call!!!]
For a free function pointer, the following will work:
<font>typedef void (*FnPtr)();
FnPtr fp;
fp();</font> i.e. you need the brackets to turn a function pointer into a function call.
For a member function pointer, you need the brackets and a class instance:
<font>typedef void(CMyClass::*Func_Ptr)(void);
CMyClass c;
Func_Ptr fp;
(c.*fp)();</font> If you want to call it from a method of the class, using the instance of the class pointed to by this , you'll need to explicitly state that:
<font>void CMyClass::Dispatch(int c)
{
CommandFunctionMap::iterator commandIter = g_cmdfuncts.find(c);
if( commandIter != g_cmdfuncts.end() )
{
(this->*commandIter->second)();
}
}
</font>
In this case, I've used the member function pointer through the iterator, rather than dereferencing it explicitly.
HTH!!!
Last modified: 20mins after originally posted --
|
|
|
|
|
|
Hello All,
I have a DLL which is builded in C# and i have to use this one into shared addin.
in shared addin project i am getting class not register error but i have prepared a simple MFC application in which i am able to crete instance of that class and also able to call function from that DLL.
can anybody tell me what is the problem with shared addin why it is not able to create instance
please share your knowledge.............
|
|
|
|
|
What does this have to do with ATL/WTL/STL?
"Any sort of work in VB6 is bound to provide several WTF moments." - Christian Graus
|
|
|
|
|
I create a new Windows Service Project. I find there is not _ATL_MIN_CRT in both Unicode Release build configuration. I think it is weird so I added _ATL_MIN_CRT in them. Then building action failed with message "unresolved external symbol _main".
why can not define _ATL_MIN_CRT in Win32 Service Project?
|
|
|
|
|
Look at the documentation:
MSDN wrote: Remember that using the _ATL_MIN_CRT macro does not guarantee that no functions from the CRT will be required. If you use a function that requires the CRT startup code to operate properly, you will get the following linker error:
LIBCMT.LIB(crt0.obj) : error LNK2001: unresolved external symbol _main Providing your own implementation of _main does not solve this problem: you must either remove reliance on the functions that require the CRT startup code, or you must either statically link the startup code in your image or dynamically link to the CRT. When _ATL_MIN_CRT is used without the /GS- compiler option, ATL headers will require the static CRT library.
What that says is that your service is using C run-time library functions that rely on having the C run-time startup code. Possibly malloc (maybe via new ?).
|
|
|
|
|
|
Looks like a regular property to me
Steve S
Developer for hire
|
|
|
|
|
sorry, the question has been modified, I mean to get the name in the atl control , not from the container.
|
|
|
|
|
But my reply still stands. Presumably the container has named the control, which it would do, presumably, by setting a property of the control...
Steve S
Developer for hire
|
|
|
|
|
I have solve the problem.
LPOLECLIENTSITE lpSite;
GetClientSite(&lpSite);
EnumAllControlNames(lpsite);
void CRadioButton::EnumAllControlNames(LPOLECLIENTSITE lpSite)
{
LPOLECONTAINER lpContainer;
LPENUMUNKNOWN lpEnumUnk;
// Note that the IOleContainer interface is currently defined as
// mandatory. It must be implemented by control containers,
// in the OLE Control Containers Guidelines.
HRESULT hr = lpSite->GetContainer(&lpContainer);
if(FAILED(hr)) {
OutputDebugString(_T("Unable to get to the container.\n"));
return;
}
// OLECONTF_EMBEDDINGS is used to retrieve OLE Controls.
// OLECONTF_OTHERS is used to retrieve other objects such as
// Visual Basic internal controls
hr = lpContainer->EnumObjects(
OLECONTF_EMBEDDINGS | OLECONTF_OTHERS,
&lpEnumUnk);
if(FAILED(hr)) {
lpContainer->Release();
return;
}
LPUNKNOWN lpUnk;
while (lpEnumUnk->Next(1, &lpUnk, NULL) == S_OK) {
LPOLEOBJECT lpObject = NULL;
LPOLECONTROLSITE lpTargetSite = NULL;
LPOLECLIENTSITE lpClientSite = NULL;
LPDISPATCH lpDisp;
hr = lpUnk->QueryInterface(
IID_IOleObject, (LPVOID*)&lpObject);
if(SUCCEEDED(hr)) {
// This is an OLE control.
// Navigate to the Extended Control because Visual Basic 4.0 uses
// Extended controls.
hr = lpObject->GetClientSite(&lpClientSite);
if(SUCCEEDED(hr)) {
// You have the IOleClientSite interface
hr = lpClientSite->QueryInterface(
IID_IOleControlSite, (LPVOID*)&lpTargetSite);
if(SUCCEEDED(hr)) {
// You have the IOleControlSite interface
// Get the IDispatch for the extended control.
// Note that Extended controls are optional in the OLE
// specifications for OLE Control Containers.
hr = lpTargetSite->GetExtendedControl(&lpDisp);
}
}
}
else {
// This is either an internal VB control or the
// VB form itself.
hr = lpUnk->QueryInterface(
IID_IDispatch, (LPVOID*)&lpDisp);
}
if(SUCCEEDED(hr)) {
VARIANT va;
VariantInit(&va);
DISPID dispid;
DISPPARAMS dispParams = { NULL, NULL, 0, 0 };
// Get the names of all the controls present in a VB form.
LPWSTR lpName[1] = { (WCHAR *)L"Name" };
hr = lpDisp->GetIDsOfNames(IID_NULL, lpName, 1,
LOCALE_SYSTEM_DEFAULT, &dispid);
if(SUCCEEDED(hr)) {
hr = lpDisp->Invoke(dispid/*0x80010000*/, IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYGET |
DISPATCH_METHOD,
&dispParams, &va, NULL, NULL);
if(SUCCEEDED(hr)) {
CString szTmp((LPCWSTR)va.bstrVal);
// szTmp now has the name.
OutputDebugString(_T("And the name is ... ") + szTmp +
_T("\n"));
}
}
lpDisp->Release();
}
// Release interface pointers.
if(lpObject) lpObject->Release();
if(lpTargetSite) lpTargetSite->Release();
if(lpClientSite) lpClientSite->Release();
lpUnk->Release();
} // End of While statement
// Final clean up
lpEnumUnk->Release();
lpContainer->Release();
}
|
|
|
|
|
Hello,
what functions that are used to block Print Screen which is key in keyboard in C++?
thanks in advance
|
|
|
|
|
I don´t know; but this might help
http://www.vbforums.com/showthread.php?t=291473
cheers
You have the thought that modern physics just relay on assumptions, that somehow depends on a smile of a cat, which isn’t there.( Albert Einstein)
|
|
|
|
|
Why would you want to block Print Screen?
"Any sort of work in VB6 is bound to provide several WTF moments." - Christian Graus
|
|
|
|
|
In a "Invisible" ATL ActiveX, is there a way to capture WM_DEVICECHANGE messages without creating a window from inside the control?
I'm calling
HDEVNOTIFY hDevNotify = RegisterDeviceNotification( GetForegroundWindow(),
&NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
But I think GetForegroundWindow is returning the handle to I.E., so ultimately the control never receives the messages.
Thanks in advance.
|
|
|
|
|
Hi everyone,
I have a class that implements an interface that derives from IDispatch directly,and I want to add a new interface which also derives from IDispatch,and then derive my class from this interface too.Expectedly,my problem is ambiguouty (did I spell it correctly??).I use COM_INTERFACE_ENTRY2 macro,but i keep getting error "cannot instantiate abstract class" error in atlcom.h
this is the IDL file:
<code>library TheLibrary
{
importlib("stdole2.tlb");
[
object,
uuid(),
dual,
nonextensible,
helpstring("Primary dispatch interface for the class."),
pointer_default(unique)
]
interface ISomething : IDispatch
{
};
[
uuid(),
helpstring("help string.")
]
coclass CSomething
{
[default] interface ISomething};
[
uuid(),
nonextensible,
helpstring("the new Interface"),
]
dispinterface INewInterface
{
properties:
methods:
[id(0), helpstring("method default"), local] HRESULT DefaultMethod(void);
};</code>
and this is the COM mapping
BEGIN_COM_MAP(CSomething)
COM_INTERFACE_ENTRY(ISomething)
COM_INTERFACE_ENTRY2(IDispatch, ISomething)
COM_INTERFACE_ENTRY(IObjectWithSite)
COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IDeskBand)
COM_INTERFACE_ENTRY_IID(IID_IDockingWindow, IDeskBand)
COM_INTERFACE_ENTRY(IDeskBand)
COM_INTERFACE_ENTRY_IID(IID_IInputObject,IInputObject)
COM_INTERFACE_ENTRY(IPropertyNotifySink)
COM_INTERFACE_ENTRY(INewInterface)
END_COM_MAP()
I tried using interface instead of dispinterface .Didn't help either.I know I'm missing something,but can't figure out what it is...
|
|
|
|
|
ajitatif angajetor wrote: ambiguouty (did I spell it correctly??)
No - ambiguity - close, though
Anyway - I've had a look through my code collection - I have a class that implements two IDispatch interfaces, in ATL 3.0 (it's an old VC6 project). Here's the relevant bit of the IDL:
[
uuid(01b836c6-51c8-4476-bf15-ae91b0fe74f6),
oleautomation,
dual
]
interface ICommands : IDispatch
{
[id(1), helpstring("method RereadEnvironment")]
HRESULT RereadEnvironment();
};
[ hidden, uuid(0309A24D-B3E7-4C6A-8ACD-B3F0F8FAA483) ] coclass ApplicationEvents
{
[default] dispinterface IDispApplicationEvents;
}
[
uuid(6c5658bc-946b-4bc7-94bf-5530cad3d654)
]
coclass Commands
{
[default] interface ICommands;
}; and code
class ATL_NO_VTABLE CCommands :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CCommands, &CLSID_Commands>,
public IDispatchImpl<ICommands, &IID_ICommands, &LIBID_DSWENVLib>,
public IDispatchImpl<IApplicationEvents, &IID_IApplicationEvents, &LIBID_DSWENVLib>
{
BEGIN_COM_MAP(CCommands)
COM_INTERFACE_ENTRY(ICommands)
COM_INTERFACE_ENTRY2(IDispatch, ICommands)
COM_INTERFACE_ENTRY(IApplicationEvents)
END_COM_MAP()
DECLARE_NOT_AGGREGATABLE(CCommands)
<class continues>
Don't know if there's anything obvious there - the COM map looks very similar to yours - what about the inheritance? Do you have an IDispatchImpl inheritance for each IDispatch interface you want to implement?
|
|
|
|
|