|
How can I launch a new child frame from a inherited CView class??
|
|
|
|
|
Do you mean a new instance of a CView derived class in an MDI app, or do you mean a new child window that is the child of a CView derived class ?
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
The idea is this:
Now that I've got the communication between my CMouse and CHtlm2View classes, I want that based in some information that my CMouse class give to my View class, launch a new chils windows with another html page displayed on it. I dont' know if this can be done from the View? Or shoul I launch it from the CMainframe class?? Anyway I don't how to do it....
|
|
|
|
|
Your document template ( which is in CMainframe ) has the method CreateNewFrame, which takes a pointer to the document associated with the view and returns a CFrameWnd*. Then you need to call InitialFrameUpdate on the template also, passing in the frame pointer and doc pointer. The best place for this is your document, because you can use theApp global variable to access the template, and 'this' for the document.
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
Can't use theApp variable. Doesn't recognize it!!
|
|
|
|
|
try putting an extern statement in, if it's an MFC app wizard generated app, then it is there. You can get the app as easily with AfxGetApp() if you need it.
Christian
After all, there's nothing wrong with an elite as long as I'm allowed to be part of it!! - Mike Burston Oct 23, 2001
|
|
|
|
|
Yep it worked! sorry I should do a little research eh?? Anyway tnx
|
|
|
|
|
Hi,
I know how to use the PSI.DLL (was it?) for checking a process' memory usage etc. But how can I get information about each process' CPU usage? I want to include a CPU usage bar in my software to display how much CPU that software is using.
Hints anyone?
|
|
|
|
|
WMI provides that information. I don't remember the specific profider. something like WIN32_Process. There are some examples of exactly what you are trying to do. I saw them while looking for some other WMI code. Just do some searches on google, code guru etc. You'll find them.
Hope this helps,
Bill
|
|
|
|
|
I managed to find PDH.DLL which uses either WMI or Registry data. I can get CPU usage from here, MSDN also contains docs on this DLL. Only problem now is I can't understand how to get process CPU usage, which functions, do I use Counters etc, how do I set them up?
An example would be perfect.
|
|
|
|
|
I don't know which method your asking about...
With WMI, get all instances of Win_32_Processor provider and query the LoadPercentage. This will return an average over 1 second.
Here is the class I ended up using in my project utilizing the PDH.dll. I create an instance of the class for each cpu on the system, query each and take an average, when I want to know the answer.
Class definition:
#ifndef __CPUUSAGE_CLASS__
#define __CPUUSAGE_CLASS__
#include<pdh.h>
class CCPUUsage {
public:
CCPUUsage();
~CCPUUsage();
#pragma message("CCPUUsage")
BOOL Init(LONG nMinTicksBetweenSamples = 1000, int iProcessor = 0);
int GetUsage(PBOOL pfNewSample = NULL);
private:
HQUERY m_hQuery;
HCOUNTER m_hCounter;
int m_nMinTicksBetweenSamples;
DWORD m_msLastTick;
int m_nLastSampledCPUUsage;
};
#endif // __CPUUSAGE_CLASS__
Class implementation:
CCPUUsage::CCPUUsage()
{
}
CCPUUsage::~CCPUUsage()
{
PdhCloseQuery(m_hQuery);
}
BOOL CCPUUsage::Init(LONG nMinTicksBetweenSamples, int iProcessor)
{
m_nMinTicksBetweenSamples = nMinTicksBetweenSamples;
m_msLastTick = 0;
// m_msLastTick = GetTickCount();
PDH_STATUS pdhs = PdhOpenQuery(NULL, 0, &m_hQuery);
CString csPath;
csPath.Format("\\Processor(%d)\\%% processor time", iProcessor);
pdhs = PdhAddCounter(m_hQuery,
TEXT(csPath), 0, &m_hCounter);
CString strDiag;
strDiag.Format("CCPUUsage::Init, pdhs = %x, Processor = %d",pdhs,iProcessor);
TRACEX(strDiag);
m_nLastSampledCPUUsage = 0;
return (pdhs == 0);
}
int CCPUUsage::GetUsage(PBOOL pfNewSample ) {
BOOL fNewSample;
if (pfNewSample == NULL)
pfNewSample = &fNewSample;
*pfNewSample = FALSE;
DWORD msCurrentTick = GetTickCount();
DWORD msLastTick = m_msLastTick;
if (msCurrentTick < msLastTick) {
// Wrap around, always sample
*pfNewSample = TRUE;
} else {
if ((msLastTick + m_nMinTicksBetweenSamples) < msCurrentTick) {
// It's been long since the last sample, get a new sample
*pfNewSample = TRUE;
}
}
CString szdiag;
if (*pfNewSample) {
if ((DWORD) InterlockedExchange((PLONG) &m_msLastTick, msCurrentTick) == msLastTick) {
PdhCollectQueryData(m_hQuery);
PDH_FMT_COUNTERVALUE pdhfcv;
PDH_STATUS stat = PdhGetFormattedCounterValue(m_hCounter, PDH_FMT_LONG, NULL, &pdhfcv);
szdiag.Format("GetStatus::PdhGetFormattedCounterValue returned %x, CStatus = %x",
stat,pdhfcv.CStatus);
TRACEX(szdiag);
if (pdhfcv.CStatus != 0) return -1; // This indicate erro (CPU doesn't exist for example)
m_nLastSampledCPUUsage = pdhfcv.longValue;
} else {
*pfNewSample = FALSE;
}
}
return(m_nLastSampledCPUUsage);
}
I create an object then call its Init method. For some reason, I don't understand, the PdhOpenQuery call returns success even if the CPU doesn't exist!! So I make an additional call to GetUsage, which returns -1 if there the requested processor doesn't exist.
Usage:
CArray<CCPUUsage*, CCPUUsage *> cpus;
int nCPUCount = 0;
while (TRUE)
cpus[nCPUCount] = new CCPUUSAge();
cpus[nCPUCount].Init(50,nCPUCount);
if (cpus[nCPUCount].GetUsage == -1) break;
nCPUCount++
}
Hope this helps
Bill
|
|
|
|
|
Well, thanks, it helps to get started on CPU Usage, but it's not what I want.
What I want is to measure the CPU Usage for my specific process. I want to know how much CPU my own software is taking, the software that this code is going to go into. I want to know if my software starts to grab 90+ % of the CPU, if it does it's an error situation and action needs to be taken.
Task Manager can obviously do it, but I am unable to find out how to do. I'm reading the PDH docs on MSDN, but it's a bit over my head and I thought someone had done it, or maybe the Task Manager code is available somewhere?
|
|
|
|
|
Here's the WMI code I used for Overall CPU usage. I believe, that by changing the query to use a different provider, you can get the info you want. I've seen an example that enumerates processes and gets info about them. In any case this class is hard won knowledge and may help.
#ifndef __SYSINFO_H_
#define __SYSINFO_H_
#include "resource.h"
#include <atlctl.h>
#include <wbemidl.h>
class ATL_NO_VTABLE CSysInfo :
public CComObjectRootEx<CComSingleThreadModel>,
public IDispatchImpl<ISysInfo, &IID_ISysInfo, &LIBID_SYSLOADLib>,
public CComControl<CSysInfo>,
public IPersistStreamInitImpl<CSysInfo>,
public IOleControlImpl<CSysInfo>,
public IOleObjectImpl<CSysInfo>,
public IOleInPlaceActiveObjectImpl<CSysInfo>,
public IViewObjectExImpl<CSysInfo>,
public IOleInPlaceObjectWindowlessImpl<CSysInfo>,
public ISupportErrorInfo,
public CComCoClass<CSysInfo, &CLSID_SysInfo>
{
public:
CSysInfo()
{
m_pUnkMarshaler = NULL;
}
~CSysInfo();
DECLARE_GET_CONTROLLING_UNKNOWN()
DECLARE_REGISTRY_RESOURCEID(IDR_SYSINFO)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CSysInfo)
COM_INTERFACE_ENTRY(ISysInfo)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IViewObjectEx)
COM_INTERFACE_ENTRY(IViewObject2)
COM_INTERFACE_ENTRY(IViewObject)
COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceObject)
COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
COM_INTERFACE_ENTRY(IOleControl)
COM_INTERFACE_ENTRY(IOleObject)
COM_INTERFACE_ENTRY(IPersistStreamInit)
COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
END_COM_MAP()
BEGIN_PROP_MAP(CSysInfo)
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
END_PROP_MAP()
BEGIN_MSG_MAP(CSysInfo)
CHAIN_MSG_MAP(CComControl<CSysInfo>)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
HRESULT FinalConstruct();
void FinalRelease()
{
m_pUnkMarshaler.Release();
}
CComPtr<IUnknown> m_pUnkMarshaler;
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
{
static const IID* arr[] =
{
&IID_ISysInfo,
};
for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
{
if (InlineIsEqualGUID(*arr[i], riid))
return S_OK;
}
return S_FALSE;
}
DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
public:
STDMETHOD(get_LoacPct)( short *pVal);
STDMETHOD(Load)();
int LoadPercentage();
HRESULT OnDraw(ATL_DRAWINFO& di)
{
RECT& rc = *(RECT*)di.prcBounds;
Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);
SetTextAlign(di.hdcDraw, TA_CENTER|TA_BASELINE);
LPCTSTR pszText = _T("ATL 3.0 : SysInfo");
TextOut(di.hdcDraw,
(rc.left + rc.right) / 2,
(rc.top + rc.bottom) / 2,
pszText,
lstrlen(pszText));
return S_OK;
}
IWbemLocator *pLoc ;
IWbemServices *pSvc ;
IEnumWbemClassObject *pEnum;
IWbemClassObject *pObj;
};
#endif //__SYSINFO_H_
#include "stdafx.h"
#include <comdef.h>
#include "SysLoad.h"
#include "SysInfo.h"
CSysInfo::~CSysInfo() {
pObj->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
}
int CSysInfo::LoadPercentage()
{
return 0;
}
STDMETHODIMP CSysInfo::Load()
{
return S_OK;
}
HRESULT CSysInfo::FinalConstruct()
{
try
{
HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if(FAILED(hres))
{
throw 101;
}
hres = CoCreateInstance(CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID *) &pLoc);
if(FAILED(hres))
{
throw 102;
CoUninitialize();
exit(1);
}
hres = pLoc->ConnectServer( _bstr_t(L"\\\\.\\root\\cimv2"),
NULL, NULL, 0, NULL, 0, 0,
&pSvc);
if(FAILED(hres))
{
throw 103;
pLoc->Release();
CoUninitialize();
exit(1);
}
hres = CoSetProxyBlanket( pSvc,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE);
if(FAILED(hres))
{
throw 104;
pSvc->Release();
pLoc->Release();
CoUninitialize();
exit(1);
}
BSTR language = SysAllocString(L"WQL");
BSTR query = SysAllocString(L"select * from Win32_Processor");
hres = pSvc->ExecQuery( language,
query,
WBEM_FLAG_FORWARD_ONLY,
NULL,
&pEnum);
SysFreeString(query);
SysFreeString(language);
if(FAILED(hres))
{
throw 105;
}
else
{
ULONG uReturned = 0;
hres = pEnum->Next( 0,
1,
&pObj,
&uReturned);
if(uReturned != 0) throw 106;
}
}
catch (int iErr)
{
}
return CoCreateFreeThreadedMarshaler(
GetControllingUnknown(), &m_pUnkMarshaler.p);
}
STDMETHODIMP CSysInfo::get_LoacPct(short *pVal)
{
BSTR strClassProp = SysAllocString(L"LoadPercentage");
VARIANT v;
HRESULT hres = pObj->Get(strClassProp, 0, &v, 0, 0);
SysFreeString(strClassProp);
if(!FAILED(hres))
{
*pVal = V_INT(&v);
}
VariantClear(&v);
return S_OK;
}
Hope this helps, My last shot
Bill
|
|
|
|
|
Oops, thanks a lot! I will digest this in upcoming days
|
|
|
|
|
Ok, some guesswork and trial and error...
First, as with another article I found on the net, the processor time parameter is Windows language dependant:
csPath.Format("\\Processor(%d)\\%% processor time", iProcessor);
changes into:
csPath.Format("\\Processor(%d)\\%% processortid", iProcessor);
...to work on my Swedish Windows. I don't know how to find this for any language yet.
To find the CPU Usage for a specific process use:
csPath.Format("\\Process(%s)\\%% processortid", sProcess);
for example:
csPath.Format("\\Process(iexplore)\\%% processortid");
for Internet Explorer CPU usage.
This does what I want now, except for that language dependency which I must solve now... (anyone know?)
|
|
|
|
|
Does anyone know what I need to do to create a CBitmap/HBITMAP out of an unsigned char array? I'm pretty sure it's a formatting issue but I just can't seem to do it. I'm a novice OpenGL developer and I know how to read and process bitmap files, but what am I doing wrong to create a CBitmap/HBITMAP from the data array?
Thanks,
- Mike
P.S. Of course I could always use LoadImage or whatever it is but I don't want to do it that way.
|
|
|
|
|
|
I was reading Item 7 of Scott Meyer's book, Effective C++ and decided to try the code. So I created my template header , a file that inherits from the template class and a driver (i.e. simple main) that tries to instantiate the new class.
I got the following errors on VC6 SP 5. Any ideas of what I am doing wrong? code is included below:
driver.cpp
c:\processdoc\c++\memorymanager\test.h(26) : error C2039: 'set_new_handler' : is not a member of 'std'
C:\ProcessDoc\C++\MemoryManager\driver.cpp(11) : while compiling class-template member function 'void *__cdecl NewHandlerSupport<class x="">::operator new(unsigned int)'
c:\processdoc\c++\memorymanager\test.h(35) : error C2039: 'set_new_handler' : is not a member of 'std'
C:\ProcessDoc\C++\MemoryManager\driver.cpp(11) : while compiling class-template member function 'void *__cdecl NewHandlerSupport<class x="">::operator new(unsigned int)'
c:\processdoc\c++\memorymanager\test.h(39) : error C2039: 'set_new_handler' : is not a member of 'std'
C:\ProcessDoc\C++\MemoryManager\driver.cpp(11) : while compiling class-template member function 'void *__cdecl NewHandlerSupport<class x="">::operator new(unsigned int)'
main.cpp
Error executing cl.exe.
MemoryManager.exe - 3 error(s), 0 warning(s)
And here is the code I have:
the main driver (driver.cpp):
#include "main.h"
void main(void)
{
x * yyy = new x();
}
the class (main.cpp & main.h):
#include "main.h"
x::x()
{
}
x::~x()
{
}
void x::test()
{
}
//////main.h
#include "test.h"
class x : public NewHandlerSupport<x>
{
public:
x();
~x();
void test ();
private:
};
the template (right off SM's book)..I called it test.h :
#include <new>
template<class t="">
class NewHandlerSupport {
public:
static new_handler set_new_handler(new_handler p);
static void * operator new(size_t size);
private:
static new_handler currentHandler;
};
template<class t="">
new_handler NewHandlerSupport<t>::set_new_handler(new_handler p)
{
new_handler oldHandler = currentHandler;
currentHandler = p;
return oldHandler;
}
template<class t="">
void * NewHandlerSupport<t>::operator new(size_t size)
{
new_handler globalHandler =
std::set_new_handler(currentHandler);
void *memory;
try {
memory = ::operator new(size);
}
catch (std::bad_alloc&)
{
std::set_new_handler(globalHandler);
throw;
}
std::set_new_handler(globalHandler);
return memory;
}
// this sets each CurrentHandler to 0
template <class t="">
new_handler NewHandlerSupport<t>::currentHandler;
|
|
|
|
|
Its telling you that set_new_handler function is not a member of the namespace std. Instead of std::set_new_handler you should use NewHandlerSupport::set_new_handler
Bret Faller
Odyssey Computing, Inc.
|
|
|
|
|
confused:
I have a WTL project where I have placed two TrackBarCtrl's on it using the
Create() function. I have a Message handler for the WM_HSCROLL event.
My problem is that I am not sure how to determine which trackbar fired the event as they
both call the same event handler. The documentation says that the lParam contains the handle
but it doesn't match up with my variables.
Please Help
Thanks,
Clint Singer
|
|
|
|
|
You're saying your two Trackbars have HWND's different to the one passed in as lParam ?
Christian
this space for rent
|
|
|
|
|
My code looks something like this:
CTrackBarCtrl* slider;
CTrackBarCtrl* speed;
...
BEGIN_MSG_MAP(CDVMSPlayerView)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_HSCROLL, OnSlide)
COMMAND_ID_HANDLER(IDC_PLAY, OnPlay)
END_MSG_MAP()
...
slider = new CTrackBarCtrl();
rect.SetRect(CPoint(0, 260), CPoint(320, 290));
slider->Create(m_hWnd, &rect, NULL, WS_CHILD | WS_VISIBLE, NULL, (HMENU) IDC_SLIDER, NULL);
speed = new CTrackBarCtrl();
rect.SetRect(CPoint(0, 300), CPoint(50, 320));
speed->Create(m_hWnd, &rect, NULL, WS_CHILD | WS_VISIBLE, NULL, (HMENU) IDC_SPEED, NULL);
...
LRESULT OnSlide(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// Need to determine whether slider or speed fired the event
if (player && player->IsRunning()) {
//if ((void*)lParam == slider) {
// player->Pause();
// player->SetFrame(slider->GetPos());
Invalidate(false);
//}
//else if ((void*)lParam == speed){
//player->SetWaitTime((21 - speed->GetPos()) * 100);
//}
}
return 0;
}
I must be doing something wrong here. If it is possible to use a switch-case clause
that would be better but slider and speed aren't constants.
|
|
|
|
|
Try getting rid of the (void*) cast (why ???), and dereference your variables. CTrackbarCtrl will almost certainly offer operator HWND, but CTrackbarCtrl* most certainly will not.
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
You're comparing an HWND with a C++ object pointer, which obviously aren't the same creatures. Do something like:
if ( (HWND)lParam == slider->m_hWnd )
--Mike--
http://home.inreach.com/mdunn/
This posting is provided "as was" with no warranties, guarantees, lotteries, or any of those little bags of peanuts you get on planes. You assume all risk for crossing the street without holding mommy's hand. © 2001 Mike's Classy Software. Member FDIC. If rash develops, discontinue use.
your with and
|
|
|
|
|
Thanks, that did the trick.
Cheers,
Clint
|
|
|
|
|