|
Read 4 bytes first to get the length value.
Now read the number of bytes identified by length.
«_Superman_»
I love work. It gives me something to do between weekends.
|
|
|
|
|
The way it's usually done is something like this:
- Read
Len from whatever you're reading from - Allocate a buffer of size
Len + sizeof Len bytes. - Copy
Len into the first sizeof Len bytes of the buffer - Read
Len bytes into the buffer after the copied value of Len - Cast the buffer pointer to FRAME* and return it
Let's presume you're reading from a C FILE :
FRAME* ReadFRAME(FILE* file)
{
int Len;
fread((void*)&Len, sizeof(Len), 1, file);
char* space = (char*)malloc(Len + sizeof(Len));
FRAME* gotFrame = (FRAME*)space;
gotFrame->Len = Len;
fread((void*)gotFrame->Text, 1, Len, file);
return gotFrame;
}
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Is there any new version of NtDsAPI.lib available for 64 bit application? If anybody knows plz reply.
Thanks & Regards
VIJITH VIJAYAN
|
|
|
|
|
|
I'm working on an application which uses a GDI+ bitmap and graphics object to double-buffer to the CView class (I don't use any Windows controls at all). This is all working very well, and I've certainly found GDI+ a little easier to work with than my previous experience working with GDI.
However, there are times when I need to be able to sustain refresh rates of around 50Hz on certain small portions of the screen. The drawing to the background bitmap isn't a big problem here, but the call to DrawImage() in OnPaint() is as it's taking a long time and chewing up a lot of processor time.
I've tried doing a GDI BitBlt() instead but while that function is fast, the creation of the HDC and HBITMAP and everything else needed isn't, and there's no speed advantage.
Has anybody got anybody got any ideas on how to speed up these calls to DrawImage()? I just don't believe that it should take up so much processor time to do so little - I know the GDI+ calls don't use hardware acceleration, but still...
|
|
|
|
|
Another idea:
Use two temp memory image(first is display,second is create in memory; change them when second is ready).
|
|
|
|
|
Thanks. Maybe I don't understand you right, but I'm not sure how that'd help. My bottleneck is the DrawImage() between the memory bitmap and the screen so wouldn't I have the same problem?
|
|
|
|
|
You dont need to create the objects every draw process. Create them at startup.
Try to draw the only changed parts of the picture or work with regions. ->CRegion
Or try subbitmaps.
Greetings from Germany
|
|
|
|
|
I'm creating the offscreen Bitmap and Graphics objects at startup, and I'm only updating a specific rectangle each screen update. It's just that the call to DrawImage() in OnPaint() takes a long time.
For example, to copy a 150x200 pixel rectangle from the memory bitmap to the screen takes 2 to 3ms on my machine, which at 50Hz screen updating hogs a lot of processor time.
What do you mean by subbitmaps?
|
|
|
|
|
substitute the DrawImage call. Make a offscreen HBM and use the faster bitblt.
Greetings from Germany
|
|
|
|
|
Redeye92 wrote: I've tried doing a GDI BitBlt() instead but while that function is fast, the creation of the HDC and HBITMAP and everything else needed isn't, and there's no speed advantage.
But I think you dont need to do it always. Once you copied to a memory dc, then only need to use BitBlt instead of each DrawImage.
- ns ami -
|
|
|
|
|
You know I was hoping that was going to be possible, but it seems that you can't write to the Graphics object whilst you've got its HDC. The code I've been using to substitute DrawImage() in OnPaint() is :
m_pbmpMemory->GetHBITMAP(Color::White, &m_hMemBitmap);
m_hMemHDC = m_gr->GetHDC();
SelectObject(m_hMemHDC, m_hMemBitmap);
BitBlt(pDC->m_hDC, rcPaint.left, rcPaint.top, rcPaint.Width(), rcPaint.Height(),
m_hMemHDC, rcPaint.left, rcPaint.top, SRCCOPY);
m_gr->ReleaseHDC(m_hMemHDC);
Am I missing something here which would save me having to do all the stuff around the BitBlt? I just can't see how to keep a hold of the HDC and HBITMAP between calls to OnPaint(), but I'd be a happy man if someone knows how to get around this.
|
|
|
|
|
Redeye92 wrote: I just can't see how to keep a hold of the HDC and HBITMAP between calls to OnPaint(),
You can create a memory dc and keep it permanantly (unless the size is changed).
For eg.
void MyDlg::CreateMemDC( CDC* pRefDC, int nWidth, int nHeight )
{
m_dcMem.CreateCompatibleDC( pRefDC );
m_bitmapMem.CreateCompatibleBitmap( pRefDC, nWidth, nHeight );
m_dcMem.SelectObject( &m_bitmapMem );
}
void MyDlg::OnInitDlg()
{
CClientDC dc( this );
CreateMemDC( &dc, 300, 200 );
}
void MyDlg::OnPaint()
{
BitBlt( pDC->m_hDC, .... .... ... , m_dcMem.m_hDC, ...... );
}
Please let me know if not clear enough.
- ns ami -
|
|
|
|
|
I think maybe I haven't explained my problem properly here...
The method you described is what I've always used before this project. But this time, instead of using GDI objects in memory, I've used GDI+ objects (which has made my offscreen drawing code a lot simpler and prettier, which was worth it). So, in my code m_pbmpMemory is a GDI+ bitmap and m_gr is a GDI+ Graphics object.
My problem is that DrawImage() is slow to the screen (the offscreen stuff isn't too bad really). I can't find a way to BitBlt from my GDI+ bitmap to the screen other than the code I posted and I was wondering if anyone else could see something I'm missing.
Hang on, I have an idea. I guess the other option would be to use GDI objects and then create the GDI+ Graphics object from that using Graphics::FromHDC() and store that to use for drawing to the offscreen bitmap. It looks like you can do it that way round, but not the other way (ie. create the Graphics object first, then get the HDC - you can only use one at a time so you need to release the HDC every time you draw to the Bitmap).
I'll go an investigate and see if that works...
|
|
|
|
|
|
Thanks for all the suggestions folks.
After some quick experiments, the solution appears to be something that I should have tried earlier but for some reason it didn't occur to me.
It looks like the best way to do double buffering quickly and efficiently in GDI+ is actually to do the double buffering part in GDI, but when you create the memory DC, also create a GDI+ Graphics object from it and store that as a member of the View/Dialog class. This way, you can draw to the offscreen GDI CBitmap object using either the DC or the Graphics object (whichever takes your fancy / suits your needs).
For the record, in this application, the difference between doing a BitBlt() and a DrawImage() in the OnPaint() command is a speed increase by a factor of between 6 and 8 times!
|
|
|
|
|
I need to do something similar. Do you mind posting the code your using?
|
|
|
|
|
Not at all...
In OnPaint()
<br />
CPaintDC dc(this);<br />
if(!m_pMemDC)<br />
{<br />
vUpdateBitmap(&dc);<br />
}<br />
CRect rcClientRect;<br />
GetClientRect(&rcClientRect);<br />
ULONG32 ulViewWidth = ulGetViewWidth();<br />
{<br />
vUpdateBitmap(&dc);<br />
}<br />
CRect rcPaint;<br />
dc.GetClipBox(rcPaint);<br />
dc.BitBlt(rcPaint.left, rcPaint.top, rcPaint.Width(), rcPaint.Height(),<br />
m_pMemDC, rcPaint.left, rcPaint.top, SRCCOPY);<br />
The vUpdateBitmap function:
<br />
<br />
if(pDC)<br />
{<br />
if(m_pMemDC)<br />
{<br />
delete m_pMemDC;<br />
}<br />
m_pMemDC = new CDC;<br />
m_pMemDC->CreateCompatibleDC(pDC);;<br />
<br />
CBitmap *m_pNewBitmap;<br />
m_pNewBitmap = new CBitmap;<br />
m_pNewBitmap->CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());<br />
m_pNewBitmap->SetBitmapDimension(rcClient.Width(), rcClient.Height());<br />
m_pMemDC->SelectObject(m_pNewBitmap);<br />
delete m_pbmpMemBitmap;<br />
m_pbmpMemBitmap = m_pNewBitmap;<br />
if(m_gr)<br />
{ delete m_gr; }<br />
m_gr = Graphics::FromHDC(m_pMemDC->m_hDC);<br />
}<br />
Then you can use the m_gr Graphics object to do your GDI+ drawing to the offscreen bitmap and the actual screen draw is done by the much faster BitBlt.
Hope that helps
|
|
|
|
|
Hi everybody,
can anyone help me ?
i'm developing a MFC Dialog based app on multi OS, which can simulate 'Windows Desktop' upto limited functionalities,
using Shell API, IContexMenu etc. With the help of CListCtrl (with Icon view) and CImageList, a Windows Desktop
has been prepared
For Context menu & PIDL, it works all fine on WIn XP,
however, on Win2k & Win98 whenever right-clicking onto non-iconic area (Desktop PIDL), my program raise error.
While debugging (& through logging), came to know that my code failed to find Desktop PIDL.
It failed at IShellFolder::GetUIObjectOf() in getting IContextMenu.
hr = m_pshObject->GetUIObjectOf (NULL, 1, (LPCITEMIDLIST *) m_pIDList, IID_IContextMenu, NULL, (void**) &InvokCmd);
Let me just elaborate through step-wise:
1). All these operation i'm performing onto 'my simulated Windows desktop'
2). To bring about the solution, hardcoding for the
Win98 desktop path C:\Windows\Desktop and for
Win2k C:\Documents and Settings\administrator\Desktop for conveting it into Desktop PIDL
Although after that, it could sucessfully displayed context-menu for desktop.
3). But when attempting to Copy-Paste operation, that is, copy any file/folder by Right-click on it,
and choose 'Paste' operation by right-click on desktop (my simulated Windows desktop),
my program performs bizarre behavior.
4). It made a new file/folder, and lable it 'Desktop' and for file-copying it shows with Windows default icon
5). One more thing, while tracing Log, analyzing for desktop PIDL i observed;
m_pIDList[0]- AppName: Desktop, AppFullPath: C:\Documents and Settings\Admin\Desktop\Desktop
in path, it shows desktop twice ...
i can't figure out how it behaves as such, while it performing nice on XP
Thanks a lot for help !
ab4rum
|
|
|
|
|
So...you supply the PIDL of the desktop folder and ask the desktop folder for the appropriate IContextMenu ?
The documentation describes the PIDL argument like this:
Address of an array of pointers to ITEMIDLIST structures, each of which uniquely identifies a file object or subfolder relative to the parent folder. Each item identifier list must contain exactly one SHITEMID structure followed by a terminating zero. Is the desktop folder a sub-folder of itself? No. I suspect that the fact it works on XP is coincidence - that or some extra checks they put in for errnous uses of the API like yours. The Windows 98/2000 behaviour kind of almost makes sense as well - the root namespace object is called 'Desktop'. You're copying something with the path 'Desktop\something' to the Desktop, so it creates a folder called Desktop as part of the paste process.
|
|
|
|
|
Sorry, i am not well at English.
My problem is that i don't know how to set sound output in left or right side of headphone.
I use portaudio class in my project to control sound output.
There is some parameters which i don't understand such as numOutputChannel.
I set it as 1 because 0 is no output.
When i set it as 2 and i set data (for output) at even point as 0, sound output in left side but sound output is different from i set numOutputChannel as 1.
Please tell me how to solve this problem.
If i set it as 2 that it is right way to control sound output in left side only, why sound output is differrent? and how to solve them?
|
|
|
|
|
nekokan wrote: When i set it as 2 and i set data (for output) at even point as 0, sound output in left side but sound output is different from i set numOutputChannel as 1.
Could you please rephrase?
- ns ami -
|
|
|
|
|
Can anyone tell me how to rename a vc++ project with its solution file.
I need step by step procedure.
Thanks in advance
|
|
|
|
|
What is it that you didn't understand in solutions provided yesterday.
You need to google first, if you have "It's urgent please" mentioned in your question.
_AnShUmAn_
|
|
|
|
|
|