(控制項) {
win32 listbox control的操作=>http://realchecko.blogspot.tw/2010/05/win32-listbox-control.html
(MFC) {
字串處理CString大全=>http://blog.xuite.net/coolflame/code/11103052-%E8%BD%89%E9%8C%84-+CString+%E6%93%8D%E4%BD%9C%E6%8C%87%E5%8D%97
(控制項) {
win32 listbox control的操作=>http://realchecko.blogspot.tw/2010/05/win32-listbox-control.html
(MFC) {
字串處理CString大全=>http://blog.xuite.net/coolflame/code/11103052-%E8%BD%89%E9%8C%84-+CString+%E6%93%8D%E4%BD%9C%E6%8C%87%E5%8D%97
由於本人在嘗試安裝軟體時缺了一些東西,便用yum下載
yum install -y ld-linux.so.2
-y 表示過程中不詢問,直接yes給過
ld-linux.so.2是我要裝的東西
================
會要設定精準的寬度是因為後面static text後面有時候要接Edit control
如果寬度設定不夠精準就會發生離很遠的情況
正常會先用方法1,如果後面不放其他控制項的話作為設定寬度就夠了
如果後面要放控制項就會用方法2
char[]轉成char*
參考網址:http://stackoverflow.com/questions/9627962/is-it-possible-to-convert-char-to-char-in-c
最簡單方法(wchar_t也適用)
method1:
char a[] = "hello";
char* p = &a[0];
method2:(避免method1的值一出scope就消失)
char a[] = "hello";
char* p;
p = strdup(a);
取得時間(目前僅在MFC用過可以,其他的沒試過)
CString csDate, csTime; // CString 只有在MFC裡面有
LPSYSTEMTIME time = new SYSTEMTIME;
::GetLocalTime(time);
// 結構
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;
// 簡易用法
csDate.Format(L"%04d/%02d/%02d", time->wYear, time->wMonth, time->wDay);
csTime.Format(L"%02d:%02d:%02d", time->wHour, time->wMinute, time->wSecond);
// create dir (if dir doesn't exist)
// dst是full path
for ( int i = 3, cur = 3; i < dst.GetLength(); i++ ) { // 3是因為有"C:\",把C槽本身當作一個資料夾
if ( dst.GetAt(i) == L'\\' ) {
if (!CFile::GetStatus(dst.Left(i), filestatus) ) // 判斷當前路徑如果不存在
if ( !CreateDirectory(dst.Left(i), NULL) ) // 如果建立資料夾失敗
MessageBox(NULL,L"create dir fail!",L"ppppppppp",MB_OK);
} // end if
}
參考網址:http://stackoverflow.com/questions/23363115/detecting-ssd-in-windows
實作在MFC
DWORD bytesReturned;
CString wstrIndex = L"";
m_EditIndexOfDrive.GetWindowTextW(wstrIndex);
if ( wstrIndex.GetLength() > 1 || wstrIndex[0] < L'0' || wstrIndex[0] > L'9' ) {
MessageBox(L"請輸入單一數字");
m_EditIndexOfDrive.SetWindowTextW(L"");
return;
} // end if
CString wstrDrivePath;
wstrDrivePath = L"\\\\?\\PhysicalDrive";
wstrDrivePath += wstrIndex;
m_Listbox.InsertString(0,L"create file...");
//As an example, let's test 1st physical drive
HANDLE hDevice = ::CreateFile(wstrDrivePath,
GENERIC_READ | GENERIC_WRITE, //We need write access to send ATA command to read RPMs
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if(hDevice != INVALID_HANDLE_VALUE)
{
m_Listbox.InsertString(0,L"check TRIM start");
//Check TRIM -- should be Y for SSD, N for Traditional HD
//_tprintf(L"TRIM=");
STORAGE_PROPERTY_QUERY spqTrim;
spqTrim.PropertyId = (STORAGE_PROPERTY_ID)StorageDeviceTrimProperty;
spqTrim.QueryType = PropertyStandardQuery;
bytesReturned = 0;
DEVICE_TRIM_DESCRIPTOR dtd = {0};
if(::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
&spqTrim, sizeof(spqTrim), &dtd, sizeof(dtd), &bytesReturned, NULL) &&
bytesReturned == sizeof(dtd)) {
//Got it
dtd.TrimEnabled ? m_Listbox.InsertString(0,L"TRIM=Y--SSD") : m_Listbox.InsertString(0,L"TRIM=N---HD");
}
else {
CString str = L"error code : ";
str.AppendFormat(L"%d", ::GetLastError());
m_Listbox.InsertString(0,str);
}
m_Listbox.InsertString(0,L"check TRIM finish");
m_Listbox.InsertString(0,L"check seekPenalty start");
//Check the seek-penalty value -- should be N for SSD
//_tprintf(L", seekPenalty=");
STORAGE_PROPERTY_QUERY spqSeekP;
spqSeekP.PropertyId = (STORAGE_PROPERTY_ID)StorageDeviceSeekPenaltyProperty;
spqSeekP.QueryType = PropertyStandardQuery;
bytesReturned = 0;
DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {0};
if(::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
&spqSeekP, sizeof(spqSeekP), &dspd, sizeof(dspd), &bytesReturned, NULL) &&
bytesReturned == sizeof(dspd))
{
//Got it
dspd.IncursSeekPenalty ? m_Listbox.InsertString(0,L"seekPenalty=Y---HD") : m_Listbox.InsertString(0,L"seekPenalty=N---SSD");
}
else
{
CString str = L"error code : ";
str.AppendFormat(L"%d", ::GetLastError());
m_Listbox.InsertString(0,str);
}
m_Listbox.InsertString(0,L"check seekPenalty finish");
}
else
m_Listbox.InsertString(0,L"createfile error");
MFC內ListBox並不會自動顯示水平捲軸,除非當你設定項目的長度超過ListBox的寬度,
因此下列做法是先記錄最大長度,超過最大長度再來設定水平捲軸
參考自:https://msdn.microsoft.com/zh-tw/library/1s0xed6b.aspx
int max_length = 0;
for ( int i = 0; i < m_vecFileList.size(); i++ ) {
m_ListFileName.AddString(m_vecFileList[i].c_str());
// 當超過最大長度時
if ( m_vecFileList[i].length() > max_length ) {
max_length = m_vecFileList[i].length();
CString str;
CSize sz;
int dx = 0;
TEXTMETRIC tm;
CDC* pDC = m_ListFileName.GetDC();
CFont* pFont = m_ListFileName.GetFont();
// Select the listbox font, save the old font
CFont* pOldFont = pDC->SelectObject(pFont);
// Get the text metrics for avg char width
pDC->GetTextMetrics(&tm);
for (int k = 0; k < m_ListFileName.GetCount(); k++) // 這裡面加總該item所有字元長度
{
m_ListFileName.GetText(k, str);
sz = pDC->GetTextExtent(str);
// Add the avg width to prevent clipping
sz.cx += tm.tmAveCharWidth;
if (sz.cx > dx)
dx = sz.cx;
}
// Select the old font back into the DC
pDC->SelectObject(pOldFont);
m_ListFileName.ReleaseDC(pDC);
// Set the horizontal extent so every character of all strings
// can be scrolled to.
m_ListFileName.SetHorizontalExtent(dx);
// should attention about listbox Hscrollbar length
}
參考文章:http://monkeycoding.com/?p=953
// file_open_test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<iostream>
#include<fstream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
ifstream fin;
ofstream fout;
fin.open("test1.txt");
//fout.open("test1.txt");
if(!fin){
return 1;
}
char ch;
//用!fin.eof()來判斷,最後會多讀一次
while(fin.peek()!=EOF) {
fin.get(ch);
printf( "%c", ch );
//fout.put(ch);
}
fin.close();
// fout.close();
system("pause");
return 0;
}
Progress Bar的使用
// create progress bar
m_hProgress = CreateWindowEx(0, PROGRESS_CLASS, NULL,WS_CHILD | WS_VISIBLE, 13, 167, 417, 17,m_hDlg, NULL, NULL, NULL);
// set progress position
int tmp = 0; // tmp 0~100
SendMessage(it_tmp->pDialog->get_hProgress(), PBM_SETPOS, (WPARAM)tmp, 0);
ListBox的使用
// ListBox::AddString(加在最下面
SendMessage( hList, LB_ADDSTRING, 0, (LPARAM)L"123321");
// ListBox::InsertString(加在最上面
SendMessage( hList, LB_INSERTSTRING, 0, (LPARAM)L"123321");
// ListBox::DeleteString
SendMessage( hList, LB_DELETESTRING, 0, 0 );
// get 現在listbox的欄位總數
int n = SendMessage(tmp_hErrMsgList,LB_GETCOUNT, 0, 0)
// 設定直的捲軸的位置在那個項目(n-1)上
SendMessage( hList, LB_SETTOPINDEX, n-1, 0);
#include <fstream>
std::wstring wstrErrMsgDump = L"jiji\n1023=\nuhfizld\nhare\nrbgya\nazerreag\n123123123123\n45645645646\n";
char c[500];
memset (c,'\0',500);
std::fstream fp;
fp.open("test.csv", std::fstream::out);//開啟檔案的寫入功能 http://www.cplusplus.com/reference/fstream/fstream/open/
if(!fp){MessageBox(L"file open error");}
for ( int i = 0, c_index = 0; i < wstrErrMsgDump.length(); i++, c_index++ ) {
if ( wstrErrMsgDump[i] != L'\n' ) {
c[c_index] = wstrErrMsgDump[i];
} // end if
else if( wstrErrMsgDump[i] == L'\n' ) {
c[c_index] = ',';
fp << c;
memset (c,'\0',500);
c_index = -1;
} // end else if
} // end for
fp.close();
}
參考網站:http://stackoverflow.com/questions/11194785/sample-atl-dialog-window
jjjj.h
class CMainDialog :
public CDialogImpl<CMainDialog>
{
public:
enum { IDD = IDD_DIALOG1 };
BEGIN_MSG_MAP(CMainDialog)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
COMMAND_ID_HANDLER(IDCANCEL, OnCommandCancel)
COMMAND_ID_HANDLER(IDOK, OnCommandOK)
END_MSG_MAP()
public:
// CMainDialog
// Window Message Handlers
LRESULT OnInitDialog(UINT nMessage, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ATLVERIFY(CenterWindow());
return 0;
}
LRESULT OnCommandOK(UINT msg, INT nIdentifier, HWND hWnd, BOOL& bHandled);
LRESULT OnCommandCancel(UINT msg, INT nIdentifier, HWND hWnd, BOOL& bHandled);
};
jjjj.cpp
HANDLE hvent; // 宣告event
hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); // 初始化為event未觸發,第三個參數為初始狀態
WaitForSingleObject( hEvent, INFINITE ); // 等待event觸發,不然就等在這
SetEvent(hEvent); // event被觸發了
WaitForSingleObject( hEvent, INFINITE ); // 遇到這個就可以通過了
ResetEvent(hEvent); // 這裡可以重新設為不通過
跨process使用,請參考:http://blog.yam.com/swwuyam/article/11418020
HANDLE CreateThread( // 成功則回傳新thread的HANDLE
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, // 可被繼承拿來用的資料結構位址
_In_ SIZE_T dwStackSize, // 執行緒的stack大小,0則表示與caller相同
_In_ LPTHREAD_START_ROUTINE lpStartAddress, // 執行緒程序名稱
_In_opt_ LPVOID lpParameter, // 32位元值之參數,可為addr
_In_ DWORD dwCreationFlags, // 為0表建立即執行,若為CREATE_SUSPEN則等呼叫ResumeThread時才執行
_Out_opt_ LPDWORD lpThreadId // 用來儲存傳回之執行緒HANDLE
);
極簡易用法 :
DWORD WINAPI ThreadFunc(LPVOID pParam) {
return 0;
}
int main() {
HANDLE hThread = CreateThread(NULL, 0, ThreadFunc, lParam, 0, NULL);
}
參考網址:http://edisonx.pixnet.net/blog/post/34345257-vector-%E5%BF%83%E5%BE%97%E6%95%B4%E7%90%86
#include <vector>
//using namespace std;
// 若前面沒using namespace std;時,後面宣告vector時皆需要加std::
// 在後方加入元素:v.push_back(i);
// 刪除最後元素:v.pop_back();
// 檢查是否為空:v.empty();
// 直接將v清空 :v.clear();
// 取得目前vector大小:v.size();
// 清除指定元素:v.erase(v.begin()+1); v.erase(v.end()-1);
// v.begin() 表示為第0個元素,等同於 v[0]
// v.end() 表示為最後一個元素,等同於 v[v.size()-1]
// 普通vector用法
std::vector<int> v1; // 宣告每個元素型態為int的vector
for ( int i = 0; i < 100; i++) // 在後方新增元素100次
v1.push_back(i);
// structure在vector內的用法
typedef struct Arr{ // 定義一個structure
int id;
int num;
} Arr;
std::vector<Arr> arr1; // 宣告每個元素型態為Arr(structure)的vector
Arr tmp;
for(i=0; i<100; i++) {
// 需要先把值填滿一個暫存用的structure
tmp.id = i+1;
tmp.num = i-1;
// 再把暫存用的structure加入到vector裡面
arr1.push_back(tmp);
}
// ---iterator用法---
std::vector<int>::iterator it = v1.begin();
// iterator表示一個指向vector(v1)某一元素的指標
// 但非真正意義上的指標,因為可以進行加減
// 見以下範例
for ( ; it != v1.end(); it++ )
int k = it; // 這時候的it代表v[0~?],同時也因為vector型態是int,所以此it也等同於int
// structure + iterator 的用法
std::vector<Arr>::iterator it = arr1.begin();
for(; it != arr.end(); it++) {
it->id++; // 這時候的it代表一個structure的指標
it->num--;
}
DialogBox的新增方式詳見:http://www.codeproject.com/Articles/227831/A-dialog-based-Win-C-program
裡有詳細教學
// gggg.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include "resource.h"
#include <string>
//***************************************************************
typedef struct S {
std::wstring wstr;
}S;
S wstr_struct;
BOOL CALLBACK DialogProc( HWND hDlg, UINT msg, WPARAM wparam, LPARAM lparam ) {
LPDRAWITEMSTRUCT lpdis;
HWND hwndList = GetDlgItem(hDlg, IDC_LIST1); // 要動控制項之前要先取得HWND
switch ( msg ) {
case WM_CREATE:
case WM_SIZE:
return true;
case WM_INITDIALOG:
return true;
case WM_COMMAND:
switch ( LOWORD(wparam) ) {
case IDOK:
SendMessage(hwndList, LB_SETHORIZONTALEXTENT, (int)(6.1 * wstr_struct.wstr.length()), 0);
// 使用LB_SETHORIZONTALEXTENT表示listbox內容會有的寬度,超出listbox外觀的寬度就會出現橫向捲軸了
// 不過他所謂的寬度表示為pixel,並非字元,而估算後*6.1大概為一個字元所佔寬度
for ( int i = 0; i <20; i++ )
SendMessage(hwndList, LB_INSERTSTRING, 0, (LPARAM)wstr_struct.wstr.c_str());
// 這樣即可在listbox內加入項目(要先換成pointer的型別)
return true;
case IDCANCEL:
EndDialog( hDlg, true );
PostQuitMessage(0);
return true;
} // end switch
break;
case WM_DRAWITEM:
lpdis = (LPDRAWITEMSTRUCT)lparam;
return true;
} // end switch
return false;
}
int main()
{
wstr_struct.wstr = L"666663333333333333333339999999999999999994477777777777777777777777777777777444444444444444444555555555";
MSG msg;
HANDLE hErrMsgEvent = CreateEvent( NULL, FALSE, true, NULL );
WaitForSingleObject( hErrMsgEvent, INFINITE ); // 等其他for迴圈跑完
int b = DialogBox( NULL, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)DialogProc );
while (GetMessage(&msg, NULL, 0, 0))
{
if (!GetMessage( &msg, NULL, NULL, NULL ))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
break;
}
}