Je suis nouveau avec MFC et essaye de l'apprendre avec un projet de base de dialogue MFC sur VS2008. Voici les archives que j'ai faites:[MFC/C++] Envoi des bits de CBitmap sur le socket, et reconstruction du côté récepteur
D'abord, j'ai réussi à afficher une liste d'images d'un dossier à un contrôle Listbox. Après cela, j'ai également géré l'événement click sur chaque ligne de la liste pour charger et afficher l'image dans le Picture Control (tapez Bitmap) sur le côté droit. Vous pouvez voir l'image ci-dessous pour une compréhension facile: Please click here for the image of my MFC dialog
Voici le code. Notez m_ListCtrl
et static_picture
sont des variables de la zone de liste et le contrôle de l'image:
void CMyClientDlg::OnLbnSelchangeList1(){
CString imagePath;
m_ListCtrl.GetText(m_ListCtrl.GetCurSel(),imagePath);
CImage picture;
picture.Load(imagePath);
if (!picture.IsNull())
{
float screenWidth = 200, screenHeight = 200;
float imageWidth = picture.GetWidth();
float imageHeight = picture.GetHeight();
//scaling:
float pictureRatio = imageWidth/ imageHeight;
float newImageWidth;
float newImageHeight;
int aligmentX = 0;
int aligmentY = 0;
if (pictureRatio <= 1)
{
newImageWidth = imageWidth*(screenHeight/imageHeight);
newImageHeight = screenHeight;
aligmentX = (screenWidth-newImageWidth)/2;
}
else
{
newImageWidth = screenWidth;
newImageHeight = imageHeight*(screenWidth/imageWidth);
aligmentY = (screenHeight - newImageHeight)/2;
}
//end scaling.
CDC *screenDC = GetDC();
CDC mDC;
mDC.CreateCompatibleDC(screenDC);
CBitmap bitMap;
bitMap.CreateCompatibleBitmap(screenDC, screenWidth, screenHeight);
CBitmap *pob = mDC.SelectObject(&bitMap);
mDC.SetStretchBltMode(HALFTONE);
picture.StretchBlt(mDC.m_hDC, aligmentX, aligmentY, newImageWidth, newImageHeight, 0, 0, imageWidth, imageHeight, SRCCOPY);
mDC.SelectObject(pob);
/*.......code to convert bitmap to BYTE* ........*/
/*.......code to send BYTE* over socket........*/
//display the bit map
static_picture.SetBitmap((HBITMAP)bitMap.Detach());
//clean up
ReleaseDC(screenDC);
}
}
Alors maintenant, je voudrais avancer d'un pas de plus, et a essayé de travailler avec prise ... et oui, je réussi envoyé et reçu simple char * ou CString sur socket.
Ce que je veux faire est: à la place d'afficher l'image sur cette boîte de dialogue, il montre l'image sur l'autre boîte de dialogue (serveur).
D'une manière ou d'une autre j'ai appris qu'il y a 2 funtions qui fonctionnent bien: SetBitmapBits()
et GetBitmapBits()
(je l'ai juste lu juste sur quelque source et n'ai aucune idead si elles conviennent à mon but ici).
Alors, j'ai ajouté ce morceau de code pour transformer le bitmap ci-dessus dans un tableau de BYTE bmpBuffer
:
BITMAP bmpProperties;
bitMap.GetBitmap(&bmpProperties);
int bmpDemension = bmpProperties.bmWidthBytes*bmpProperties.bmHeight;
BYTE* bmpBuffer=(BYTE*)GlobalAlloc(GPTR, bmpDemension);
bitMap.GetBitmapBits(bmpDemension,bmpBuffer);
envoyer ensuite ce tableau sur la douille:
UpdateData(TRUE);
char *socketBuffer = reinterpret_cast<char*>(bmpBuffer);
send(m_ClientSocket, socketBuffer, sizeof(socketBuffer), 0);
//clean up after send
GlobalFree((HGLOBAL)bmpBuffer);
autre boîte de dialogue. Note: Je le demension hardcoded du bitmap à 160000, pour simplifier le problème:
void CMyServer2Dlg::OnReceive(){
char *socketBuffer = new char [1025];
int iLen;
iLen = recv(m_sConnected, socketBuffer, 1025, NULL);
if(iLen==SOCKET_ERROR)
{
AfxMessageBox("Could not Receive");
}
else
{
BYTE* bmpBuffer = reinterpret_cast<BYTE*>(socketBuffer);
//re-construct the bitmap
CBitmap clone;
CDC *screenDC = GetDC();
CDC mDC;
mDC.CreateCompatibleDC(screenDC);
clone.CreateCompatibleBitmap(screenDC, 200, 200);
clone.SetBitmapBits(160000,bmpBuffer);
//Picture control(type bitmap) has variable "static_picture"
static_picture.SetBitmap((HBITMAP)clone.Detach());
UpdateData(FALSE);
ReleaseDC(screenDC);
GlobalFree((HGLOBAL)bmpBuffer);
}
delete socketBuffer;
Et, ça ne marche pas ... S'il vous plaît me dire où ai-je gâcher? Et désolé pour le poste long .....
Avoir un +1 pour rechercher des solutions (oui, GetBitmapBits et SetBitmapBits sont les bonnes fonctions, je pense). Mais, que voulez-vous dire par "ne fonctionne pas"? – immibis
Merci pour votre réponse. Du côté du récepteur, il n'affiche que la couleur noire 200x200, pas l'image sur laquelle j'ai cliqué du côté de l'expéditeur. J'ai également essayé de reconstruire la carte de bits du côté de l'expéditeur pour les tests et cela fonctionne normalement. –
Corrigez-moi si c'est le cas. Votre tampon de réception est 1025, et votre taille de bitmap est 160000. Le tampon est-il assez gros? –