Các bác lập trình eVC có biết cách nào copy buffer màn hình không.
Em đang cần tạo một CDC, Vẽ , chỉnh sửa trên nó rồi mới đưa ra DC màn hình nhưng loay hoay mãi không làm được.
Kính mong các bác chỉ dạy.
Bác tạo một cái CDC có chức năng như bộ đệm, tạo một bitmap và gắn với cái DC đó; vẽ lên DC vừa tạo, sau đó dùng BitBlt để copy ra DC màn hình.
Ví dụ:
CDC memDC;
CBitmap memBmp;
memDC.CreateCompatibleDC(pDC);
memBmp.CreateCompatibleBitmap(pDC, 100, 100);
CBitmap *pOldBmp = memDC.SelectObject(&bmp);
//Vẽ trên memDC…
pDC->BitBlt( 0, 0, 100, 100, &memDC, 0, 0, SRCCOPY ); //copy ra màn hình
memDC.SelectObject(pOldBmp);
memDC.SelectObject(&bmp); là đủ
thực ra ko cần khai thêm pOldBmp vẫn OK. Cái pOldBmp chỉ để lưu lại bmp cũ của memDC. Cái này chỉ cần thiết nếu ta muốn lưu lại bimap của device context hiện thời
đã làm được từ mấy hôm trước, nhưng cũng rất cảm ơn bác đã quan tâm. Gặp vấn đề mới sẽ hỏi thêm bác nhiệt tình
Sao lại không cần thiết hả bác! Nếu bác ko làm vậy, sẽ có lúc bác thấy lỗi ;). Bác phải làm vậy mới giải phóng tài nguyên cho máy được chứ. Win bây giờ cũng xịn rồi, chứ Win cũ bác thử ko làm vậy xem, tèo OS ngay!
Em không nghĩ là lỗi nếu ko có poldBmp vì sau khi dùng memDC thường ta sẽ giải phóng nó luôn.Không biết có đúng không nhỉ.
Em lại có vấn đề mới, các bác có biết cách nào để capture cái bimap của một dc nào đó không. em thấy hàm CDC.selectObject(&bmpTemp) se trả ra CBitmap* là con tro tro den cai bitmap hien thoi của nó, tuy nhiên em dùng hàm này để lấy bitmap ra thì ko thể được.
Cảm ơn các bác
Khi bạn attach 1 GDI (resource) object như vậy, nếu bạn ko deselect (pOld = dc.SelectObject() sẽ deselect object hiện tại mà dc đang giữ, tức là đẩy object đó ra) thì tài nguyên đó sẽ không thể giải phóng được do nó đang bị nắm giữ và sẽ sinh re leack resource (mem). Bạn muốn test thì dùng Win 98 sẽ thấy ngay kết quả (thử làm 1 vòng for xem, máy sẽ tèo ngay). Do Win XP quản lý mem khá tốt nên ta thử trên WinXp sẽ ko thấy được vì ngay sau khi thoát chương trình thì toàn bộ tài nguyên của chương trình đó sẽ được giải phóng. Vả lại nếu ko cần làm như vậy thì chẳng có lý do gì mà trong tất cả các ví dụ của MSDN cũng đều làm như vậy.
Khi ta khai báo 1 biến trong hàm, khi ra khỏi hàm đó thì biến đó sẽ tự động được giải phóng, đúng ko? Nhưng bạn thử đọc trong MSDN xem, riêng đối với các biến GDI, mặc dù nó có thể tự giải phóng, nhưng MS luôn khuyên ta nên dùng hàm để giải phóng, vd: ReleaseDC(&dc);
Ý capture của bạn ở đây là sao? mình ko hiểu, bạn muốn save cái bitmap đó? nếu vậy thì phụ thuộc vào kỹ thuật lập trình, tức là giống như save file thôi, bạn phải save header, data, nén data, …
Các biến khai báo local bên trong hàm được cấp phát trong stack. Vì vậy khi thoát khỏi hàm, các biến này được giải phóng. Còn các GDI object (hay bất cứ object nào của Windows) thì cần phải gọi hàm release như DellAximX5 nói. Nếu bạn đã sử dụng Win32 API để viết chương trình, bạn sẽ thấy các đối tượng như brush, font, bitmap… đều phải gọi hàm DeleteObject sau khi đã sử dụng xong. Trên MFC, lời gọi hàm này được thực hiện trong destructor của các class MFC như CBitmap. MSDN khuyến cáo không được gọi DeleteObject khi đối tượng còn đang được sử dụng trong DC (bạn tra hàm DeleteObject trong MSDN sẽ thấy). Như trong đoạn code ở trên, bmp là biến local, do vậy nó sẽ bị release khi thoát khỏi hàm, dẫn đến destructor được gọi. Nếu bạn bỏ lời gọi memDC.SelectObject(pOldBmp), tức là bmp vẫn được memDC sử dụng, lúc này sẽ vi phạm nguyên tắc trên.
Trong MSDN có hướng dẫn “Storing an Image”. Bác tra BITMAPFILEHEADER, sau đó lần ngược ra phần “using bitmap” sẽ thấy.
Ý em không phải là ko cần giải phóng. Em muốn nói là không cần khai thêm
CBitmap *pOldbmp và có thể bỏ dòng lệnh memdc.selecobject(pOldbmp ). Thay vào đó ta chỉ cần giải phóng memdc là được. Để rõ hơn sau đây là đoạn code của em, các bác xem xem có lỗi không nhé(em chạy trên WInCE bét nhè mà chưa lỗi thì phải):
CDC buffDC;
CBitmap bmpBuffer;
buffDC.DeleteDC();
bmpBuffer.DeleteObject();
bmpBuffer.CreateCompatibleBitmap(&dc,xc,yc);
buffDC.CreateCompatibleDC(&dc);
buffDC.SelectObject(&bmpBuffer);
// vẽ , thao tác đồ họa với buffDC
dc.BitBlt(0,0,xc,yc,&buffDC,1,1,SRCCOPY);
ReleaseDC(&buffDC);
-
Capture màn hình em làm được rồi bác à. Em làm cái đó để tăng tốc độ xử lý đồ họa. Trong một số trường hợp, ta có thể capture lại màn hình của device context lúc đó, sau khi xử lý một số tác vụ ta load lại bimap đó lên dc hiện thời, tránh việc vẽ lại các đối tượng đồ họa trong onPaint(). Một ví dụ cực kỳ cụ thể các bác cũng thấy là trong chương trình handMap, trong quá trình sử dụng công cụ PAN, bác sẽ thấy nó dịch chuyển bitmap của DC hiện thời chứ không phải là RePaint() một cách liên tục.
-
Em lại phát sinh ra vấn đề mới. Các bác có biết cách nào tăng tốc việc đọc file dữ liệu không. Em đọc một file text 60kb vào một mảng mà PDA của em chạy mất gần 10s mới đau chứ. Tốc độ như thế là có vấn đề đúng không các bác
Rất cảm ơn các bác góp ý nhiệt tình.
Đợi phản hồi…
Bác đã dùng thử kỹ thuật file-mapping chưa? Có lẽ sẽ cải thiện được tốc độ đọc file.
Cac bac noi lam em thay minh dot qua. Chang biet filemapping la gi het. Bac chi dup em dc ko
File-mapping sử dụng các hàm CreateFileMapping để mở file, sau đó gọi hàm MapViewOfFile để ánh xạ nội dung file vào không gian bộ nhớ của process. Kết quả trả về là một con trỏ trỏ tới vùng nhớ chứa nội dung của file. Thực hiện truy xuất vùng nhớ này (đọc, ghi … - tùy thuộc vào flag khi gọi hai hàm trên). Sau khi đã truy xuất xong, kết thúc bằng UnmapViewOfFile & CloseHandle.
Có lẽ em trình bày chưa clear vấn đề của mình :
- Tại PC em kết xuất ra một số dữ liệu, đây chính là dữ liệu nguồn cho chương trình của PDA.
- Em lựa chọn lưu trữ dưới dạng text.
- Chương trình trên PDA đọc toàn bộ dữ liệu này vào các mảng được khai báo. Đọc file duy nhất một lần từ đầu đến cuối, và nạp vào từng mảng đã khai báo.
- Em sử dụng cách đọc lần lượt từng dòng cho đến khi hết file thì thôi.
Với cách đọc này , chỉ tính riêng phần đọc file. Con 1945 của em đọc mất 10 giây cho một file 60K (khoảng 1000 dòng).
Em cảm thấy là đã làm sai cái gì đó và có thể có cách cải thiện. Các bác sáng suốt chỉ giúp em xem em có sai sót ở đâu không ạ.
Cảm ơn các bác nhé.
Hy vọng em sớm hoàn thành sản phẩm để phục vụ cộng đồng handheldVN.
Theo mình nghĩ thì tốc độ đọc chậm là do bác đã đọc từng dòng văn bản chứ không phải đọc cả khối dữ liệu. Nếu đọc toàn bộ cả file vào vùng nhớ, số lần truy cập thiết bị lưu trữ giảm rõ rệt, dẫn tới tăng tốc độ. Nếu file có kích thước quá lớn thì không thể áp dụng phương pháp này do thiếu bộ nhớ. Tuy nhiên với 60KB thì áp dụng được.
Cảm ơn bác nhiều nhé. Em sẽ làm theo lời khuyên của bác. Rất vui được làm quen với mọi người.