-
14-05-2014, 07:15 PM #1Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Mã : Liệt kê tất cả các tập tin theo 1 đuôi mở rộng trong 1 ổ đĩa
Mã này mình viết đã lâu rồi, nay post lên nhờ anh em tham khảo. Bạn nào giúp mình khử đệ quy cho mã tốt hơn không ? Cám ơn.
Mã:#include<windows.h> // Cần thiết cho lập trình Windows#include<time.h> // Cần cho hàm srand()#include<shlwapi.h> // Window Shell#include"resource.h" // Icon và Hộp thoại#pragma comment(lib,"shlwapi.lib") // Phân giải cho Shelltypedef struct // Cấu trúc truyền thông tin giữa cửa sổ và luồng việc{ HWND hDlg; HWND hList,hStatic; CHAR szDrive[3]; CHAR szExt[5]; DWORD dwCount;}PARAM,*PPARAM; void EnumFile(PCHAR szFolder,PPARAM pParam){ WIN32_FIND_DATA wfd; CHAR szFind[MAX_PATH*2]; HANDLE hFind; wsprintf(szFind,"%s\\*.*",szFolder); // Tìm tất cả if(INVALID_HANDLE_VALUE != (hFind = FindFirstFile(szFind,&wfd))) { do { if(wfd.cFileName[0] != '.') // Không xét thư mục cha và thư mục gốc { wsprintf(szFind,"%s\\%s",szFolder,wfd.cFileName); if(PathIsDirectory(szFind)) // Chuỗi tìm thấy là thư mục EnumFile(szFind,pParam); // Gọi đệ quy vào sâu trong thư mục con else if(lstrcmpi(PathFindExtension(szFind),pParam->szExt) == 0) // Nếu là tập tin có đuôi đang tìm kiếm { // Ghi vào listbox và hiển thị cập nhật số tập tin đã tìm được vào static label SendMessage(pParam->hList,LB_SETCURSEL,SendMessage(pParam->hList,LB_ADDSTRING,0,(LPARAM)szFind),0); wsprintf(szFind,"%d",++pParam->dwCount); SetWindowText(pParam->hStatic,szFind); } } } while(FindNextFile(hFind,&wfd)); // Tìm tên kế tiếp FindClose(hFind); // Chấm dứt tìm trong thư mục này }}DWORD WINAPI StartThread(PVOID pVoid){ PPARAM pParam = (PPARAM)pVoid; SendMessage(pParam->hList,LB_RESETCONTENT,0,0); SetWindowText(pParam->hStatic,"0"); EnumFile(pParam->szDrive,pParam); SendMessage(pParam->hDlg,WM_USER,0,0); // Gởi thông báo hoàn thành tới cửa sổ chính return 0;}BOOL CALLBACK DlgProc(HWND hDlg,UINT message,WPARAM wparam,LPARAM lparam){ static HANDLE hThread; static HWND hList,hCombo,hEdit,hStatic; static HBRUSH hbrBack; // But vẽ nền của hộp thoại static PARAM param; // Biến tham số cho luồng việc UINT uDrive; char root[3] = " :"; // Chuỗi thư mục gốc char szExt[5]; // Chuỗi đuôi mở rộng cho tìm kiếm char c; int iLen; switch(message) { case WM_INITDIALOG: // Nạp Icon cho cửa sổ hộp thoại SetClassLong(hDlg,GCL_HICON,(LONG)LoadIcon((HINSTANCE)lparam,MAKEINTRESOURCE(IDI_ICON1))); srand(time(NULL)); hbrBack = CreateSolidBrush(RGB(rand()&255,rand()&255,rand()&255)); hEdit = GetDlgItem(hDlg,IDC_EDIT1); hCombo = GetDlgItem(hDlg,IDC_COMBO1); hList = GetDlgItem(hDlg,IDC_LIST1); hStatic = GetDlgItem(hDlg,IDC_STATIC1); SetWindowText(hEdit,"exe"); for(c='C';c<='Z';c++) { root[0] = c; uDrive = GetDriveType(root); if(uDrive == DRIVE_REMOVABLE || uDrive == DRIVE_FIXED || uDrive == DRIVE_CDROM || uDrive == DRIVE_RAMDISK) SendMessage(hCombo,CB_ADDSTRING,0,(LPARAM)root); else break; } SendMessage(hCombo,CB_SETCURSEL,0,0); return TRUE; case WM_USER: // Nhận thông báo hoàn thành từ luồng việc hThread = NULL; EnableWindow(GetDlgItem(hDlg,IDOK),TRUE); // Cho phép nút Start return TRUE; case WM_COMMAND: switch(LOWORD(wparam)) { case IDC_BUTTON1_STOP: // Nút Stop được nhấn if(hThread) { TerminateThread(hThread,0); // Chấm dứt luồng việc hThread = NULL; } EnableWindow(GetDlgItem(hDlg,IDOK),TRUE); // Cho phép nút Start return TRUE; case IDOK: // Nút Start được nhấn iLen = GetWindowTextLength(hEdit); if(iLen < 1 || iLen > 3) { MessageBox(hDlg,"Ext id invalid","ListFile",0); return TRUE; } ZeroMemory(¶m,sizeof(PARAM)); GetWindowText(hEdit,szExt,GetWindowTextLength(hEdit)+1); wsprintf(param.szExt,".%s",szExt); param.hStatic = hStatic; param.hList = hList; param.dwCount = 0; param.hDlg = hDlg; GetWindowText(hCombo,param.szDrive,GetWindowTextLength(hCombo)+1); hThread = CreateThread(NULL,0,StartThread,¶m,0,NULL); // Tạo ra luồng việc mới EnableWindow(GetDlgItem(hDlg,IDOK),FALSE); // Không cho phép nút Start return TRUE; case IDCANCEL: // Nút Close được nhấn SendMessage(hDlg,WM_CLOSE,0,0); return TRUE; } break; case WM_CTLCOLORDLG: // Thông điệp yêu cầu bút vẽ để vẽ nền hộp thoại return (int)hbrBack; case WM_CLOSE: if(hThread) TerminateThread(hThread,0); DeleteObject(hbrBack); EndDialog(hDlg,0); return TRUE; } return FALSE;}int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev,LPSTR lp,int nShow){ DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DlgProc,(LPARAM)hInstance); return 0;}
_ Icon: IDI_ICON1
_ Dialog : IDD_DIALOG1
_ Listbox : IDC_LIST1(NoSort), Combobox : IDC_COMBO1(DropList,NoSort), Edit : IDC_EDIT1, Static : IDC_STATIC1, Button : IDC_BUTTON1
Được sắp xếp như hình bên dưới khi thực thi
View more random threads:
- Làm sao để click chuột được vào game đã trận các hàm API click mouse
- Mouse Scroll Control VC++ Windows ?
- Sử dụng WMI để ghi giá trị vào object của NetworkApdaper không được. Nguyên nhân ?
- Tại sao hook NtShutDownSystem thì bị reset máy
- Lập trình VC++ | Bảo Vệ ENDTASK tại sao không chạy tốt
- Chống xung đột Multi - Thread Trong VC++ API
- Cách lấy Icon của file dựa trên phần mở rộng của file ấy?
- Cách viết ứng dụng gọi tự động một chương trình thực thi
- Làm thế nào chương trình vẫn hoạt động khi MessageBox được show lên?
- Tạo toolbar 24bit color và đổi màu nền toolbar
-
10-05-2016, 09:01 AM #2Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
cái mã này là dùng thư viện đồ họa j vậy bạn?
-
10-05-2016, 01:02 PM #3Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Gửi bởi binhln
-
12-05-2016, 08:26 AM #4Junior Member
- Ngày tham gia
- Sep 2015
- Đang ở
- 89 Tam Trinh - Hoàng Mai - Hà Nội
- Bài viết
- 0
Gửi bởi Van8Hien62
-
12-05-2016, 04:09 PM #5Junior Member
- Ngày tham gia
- Sep 2015
- Đang ở
- 24 Rạch Bùng Binh , P10,Q3 , HCM
- Bài viết
- 0
Dùng BB Code cho dễ đọc (xem reply #1)
//
IDE nó highLight, đánh số dòng, ...
//
Bắt người khác đánh vần, đọc từng chữ, ... đọc xong đã mệt còn sức đâu giúp ai.
-
12-05-2016, 07:28 PM #6Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
soạn thảo bên ngoài VS rồi lưu với đuôi *.c, sau đó có thể biên dịch bằng command line (command prompt).
//
cl /? - for help (VC)
//
bcc32 - for Borland C
-
13-05-2016, 11:20 AM #7Banned
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
@Van8Hien62 : Cám ơn bạn đã chia sẻ.
Quay trở lại với vấn đề của binhIn. Có vài nhận xét :
_ Mã của bạn hơi lủng củng và hơi khó đồng bộ, bạn muốn ghi vào tập tin nhưng lại tìm kiếm tập tin trong dữ liệu lưu trên bộ nhớ.
_ Với các chuỗi thì bạn không thể gán từ chuỗi này sang chuỗi khác (chỉ có thể gán địa chỉ thôi) mà phải copy bộ nhớ như dùng hàm memcpy chẳng hạn, trong mã của bạn thì có thể dùng wsprintf cũng được.
_ Viết mã hơi lẫn lộn : nếu printf thì không cout và ngược lại. Dẫn tới định dạng chuỗi không chính xác.
Mã bên dưới viết tạm cho bạn tham khảo, khi duyệt thì nó lưu vào bộ nhớ, khi tìm thì nó tìm từ bộ nhớ. Bạn nhớ thêm mã kiểm tra nhập liệu từ người sử dụng, mã còn nhiều thiếu sót, nhờ các bạn khác xem dùm.
Mã:#define _CRT_SECURE_NO_WARNINGS#include "stdafx.h"#include <Windows.h>#include <shlwapi.h>#include <iostream>#include <vector>#pragma comment(lib,"Shlwapi.lib")using namespace std; typedef struct{ CHAR szName[MAX_PATH / 2]; // Lưu tên file CHAR szPath[MAX_PATH * 2]; // Lưu đường dẫn file} DATA, *PDATA; // szFolder : [in] thư mục đang duyệt tìm các thư mục con và tập tin// pVector : [in] biến vector chứa dữ liệu// nLevel : [in] độ sâu đệ quy - cũng là xác định khoảng cách canh lềvoid find(PCHAR szFolder, vector<PDATA> &pVector, int nLevel){ WIN32_FIND_DATA w; CHAR szFind[MAX_PATH * 2]; HANDLE hFind; wsprintf(szFind, "%s\\*.*", szFolder); hFind = FindFirstFile(szFind, &w); if (hFind != INVALID_HANDLE_VALUE) { do { if (w.cFileName[0] != '.') { for (int i = 0; i < nLevel; i++) // Chừa các khoảng trắng phân cấp cho độ sâu, 2 space cho 1 cấp cout << " "; //printf(" "); wsprintf(szFind, "%s\\%s", szFolder, w.cFileName); if ((PathIsDirectory(szFind))) { cout << "+ " << w.cFileName << " "; // Dấu + đại diện cho thư mục find(szFind, pVector, nLevel + 1); } else // Là tập tin { cout << "- " << w.cFileName << " "; // Dấu - đại diện cho tập tin PDATA pData = new DATA; wsprintf(pData->szName, w.cFileName); wsprintf(pData->szPath, szFolder); pVector.push_back(pData); // Lưu vào Vector } } } while (FindNextFile(hFind, &w)); FindClose(hFind); }} // Tìm tập tin lưu trữ trong Vectorvoid searchname(vector<PDATA> &pVector, PCHAR szName){ PDATA pData; int iIndex = 0; for (vector<PDATA>::iterator iter = pVector.begin(); iter != pVector.end(); ++iter) { pData = *iter; if (!_strcmpi(szName, pData->szName)) cout << ++iIndex << ": " << pData->szPath << "\\" << pData->szName << " "; } if (!iIndex) cout << "Khong co file can tim ";} int main(){ vector<PDATA> Vector; int select; char name[50]; int bFind = 0; cout << "Chuong trinh tim kiem file"; do { if(bFind) cout << " 2: Search 0: Exit "; else cout << " 1: Quet File 0: Exit "; cin >> select; // Chưa kiểm tra nhập switch (select) { case 0: return 0; case 1: // Khi thử nghiệm chỉ nên duyệt 1 ổ đĩa ít dữ liệu. //find("C:", Vector, 0); find("D:", Vector, 0); //find("E:", Vector, 0); bFind = 1; // Đã có duyệt các tập tin break; case 2: if (!bFind) { cout << "================== Quet File ??? ======================"; break; } cout << "Nhap ten file can tim : "; cin >> name; // Chưa kiểm tra nhập searchname(Vector, name); break; default: cout << "Nhap sai so "; break; } } while (cin.get() != '0'); return 0;}
-
13-05-2016, 04:25 PM #8Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Gửi bởi MHoang
Để biên dịch theo mode command prompt, bạn cần biết cách thiết lập biến, đường dẫn (Environment Variables). Nó dài dòng nên không tiện trình bày ở đây.
Với Ms Microsoft Visual Studio X, nó là cl.exe
a - đọc hướng dẫn, trong MsDN là khá đầy đủ
b - trong command prompt, gõ : >\CL.exe /?
Đâu phài lúc nào cũng phụ thuộc vào IDE, chỉ biết cắm đầu trong chuồng, một không gian nhỏ mà thành lập trình giỏi được.
-
13-05-2016, 06:40 PM #9Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Trích dẫn : Bạn có thể thay bộ đệm (cache) và độ rộng, cao của command prompt (cmd.exe)
Ờ, cái này mình chưa từng tìm hiểu vì cũng it khi đụng tới nó. Cho tìm hiểu thêm chút :
1. Hộp thoại trên là từ chương trình bạn viết hay là của Windows, máy mình dùng Windows8 nên không có trang tab Layout, hoặc mình không biết tìm nó ở chỗ nào.
2. Theo như hộp thoại trên thì chiều cao (số dòng mà buffer lưu lại) tối đa là bao nhiêu. Theo mình nhớ không lầm thì điều khiển Up-Down giữ giá trị mà hiển thị trên Edit là một số int và như vậy số dòng có trong cửa sổ cmd vẫn là hữu hạn. Như vậy, kể cả trong trường hợp đã nhấc bộ đệm lên cao nhất, gặp các điều kiện không thuận lợi, cmd vẫn không thể không cắt bớt mà nó vẫn cứ phải cuốn chiếu và loại trừ những dòng ở phía đầu phải không ? Cần hiểu thêm về cái này. (Theo mình thấy ổ đĩa chủ của một máy có thể có tổng số thư mục và tập tin là lớn hơn giới hạn của số int thì cũng không phải là chuyện lạ)
Vấn đề biên dịch bằng dòng lệnh, liên kết bằng dòng lệnh, rất dài dòng như bạn nói, nên nếu có thảo luận, chúng ta hãy mở một đề tài khác. Chúng ta không cần phụ thuộc vào IDE khi đúng mục đích, khi mục tiêu chưa phải là biên dịch dòng lệnh thì IDE vẫn là công cụ thuận lợi nên có gì phải từ chối nó (?!).
-
13-05-2016, 07:11 PM #10Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
1 - Tôi dùng Win7, ở Title Bar của cmd.exe, right-click menu.Propertes
2 - buffer max là 9999 lines. Nó hữu hạn và chưa đủ lớn cho các log, trong trường hợp đó tôi xuất ra file (text file lớn mờ bằng notepad của chính Windows không hiệu quả, chậm, nặng; nên mở bằng notepad++):
abc.exe opts >toFile.dat
Biên dịch bằng dòng lệnh không thay thế IDE, nhất là các bạn mới làm quen với lập trình. Nó cho bạn biết có một công cụ khác, mà thực sự IDE gọi và lấy kết quả từ đó. Nó mạnh mẽ hơn IDE, làm được những cái trong IDE không hỗ trợ.
Thanh lý pallet nhựa cũ Đaklak Trải dài trên vùng đất Daklak, những chiếc pallet nhựa cũ Đaklak nằm rải rác như những bức tranh tĩnh lặng, kể lể về những chặng đường mà chúng đã đi qua. Những đường...
Thanh lý pallet nhựa cũ Đaklak