VC 學習筆記

vc學習筆記

VC學習筆記1:按鈕的使能與禁止

用ClassWizard的Member Variables爲按鈕定義變量,如:m_Button1;

m_Button1.EnableWindow(true); 使按鈕處於允許狀態
m_Button1.EnableWindow(false); 使按鈕被禁止,並變灰顯示


VC學習筆記2:控件的隱藏與顯示

用CWnd類的函數BOOL ShowWindow(int nCmdShow)可以隱藏或顯示一個控件。

例1:
CWnd *pWnd;
pWnd = GetDlgItem( IDC_EDIT1 ); //獲取控件指針,IDC_EDIT爲控件ID號
pWnd->ShowWindow( SW_HIDE ); //隱藏控件

例2:
CWnd *pWnd;
pWnd = GetDlgItem( IDC_EDIT1 ); //獲取控件指針,IDC_EDIT爲控件ID號
pWnd->ShowWindow( SW_SHOW ); //顯示控件

以上方法常用於動態生成控件,雖說用控件的Create函數可以動態生成控件,但這種控件很不好控制,所以用隱藏、顯示方法不失爲一種替代手段。


VC學習筆記3:改變控件的大小和位置

用CWnd類的函數MoveWindow()或SetWindowPos()可以改變控件的大小和位置。

void MoveWindow(int x,int y,int nWidth,int nHeight);
void MoveWindow(LPCRECT lpRect);
第一種用法需給出控件新的座標和寬度、高度;
第二種用法給出存放位置的CRect對象;
例:
CWnd *pWnd;
pWnd = GetDlgItem( IDC_EDIT1 ); //獲取控件指針,IDC_EDIT1爲控件ID號
pWnd->MoveWindow( CRect(0,0,100,100) ); //在窗口左上角顯示一個寬100、高100的編輯控件

SetWindowPos()函數使用更靈活,多用於只修改控件位置而大小不變或只修改大小而位置不變的情況:
BOOL SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);
第一個參數我不會用,一般設爲NULL;
x、y控件位置;cx、cy控件寬度和高度;
nFlags常用取值:
SWP_NOZORDER:忽略第一個參數;
SWP_NOMOVE:忽略x、y,維持位置不變;
SWP_NOSIZE:忽略cx、cy,維持大小不變;
例:
CWnd *pWnd;
pWnd = GetDlgItem( IDC_BUTTON1 ); //獲取控件指針,IDC_BUTTON1爲控件ID號
pWnd->SetWindowPos( NULL,50,80,0,0,SWP_NOZORDER | SWP_NOSIZE ); //把按鈕移到窗口的(50,80)處
pWnd = GetDlgItem( IDC_EDIT1 );
pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER | SWP_NOMOVE ); //把編輯控件的大小設爲(100,80),位置不變
pWnd = GetDlgItem( IDC_EDIT1 );
pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER ); //編輯控件的大小和位置都改變
以上方法也適用於各種窗口。


VC學習筆記4:什麼時候設定視中控件的初始尺寸?

我在CFormView的視中加入了一個編輯控件,在運行時使它充滿客戶區,當窗口改變大小時它也跟着改變。
改變控件尺寸可以放在OnDraw()函數中,也可放在CalcWindowRect()函數中,當窗口尺寸發生變化時,它們都將被執行,且CalcWindowRect()函數先於OnDraw()函數,下例是在CalcWindowRect()函數中修改控件尺寸。
重載VIEW類的CalcWindowRect函數,把設定控件的尺寸的語句加入這個函數中。
例:
void CMyEditView::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType)
{
// TODO: Add your specialized code here and/or call the base class

CFrameWnd *pFrameWnd=GetParentFrame(); //獲取框架窗口指針

CRect rect;
pFrameWnd->GetClientRect(&rect); //獲取客戶區尺寸

CWnd *pEditWnd=GetDlgItem(IDC_MYEDIT); //獲取編輯控件指針,IDC_MYEDIT爲控件ID號
pEditWnd->SetWindowPos(NULL,0,0,rect.right,rect.bottom-50,SWP_NOMOVE | SWP_NOZORDER); //設定控件尺寸,bottom-50是爲了讓出狀態條位置。

CFormView::CalcWindowRect(lpClientRect, nAdjustType);
}


VC學習筆記5:單選按鈕控件(Ridio Button)的使用

一、對單選按鈕進行分組:
每組的第一個單選按鈕設置屬性:Group,Tabstop,Auto;其餘按鈕設置屬性Tabstop,Auto。

如:
Ridio1、Ridio2、Ridio3爲一組,Ridio4、Ridio5爲一組

設定Ridio1屬性:Group,Tabstop,Auto
設定Ridio2屬性:Tabstop,Auto
設定Ridio3屬性:Tabstop,Auto

設定Ridio4屬性:Group,Tabstop,Auto
設定Ridio5屬性:Tabstop,Auto

二、用ClassWizard爲單選控件定義變量,每組只能定義一個。如:m_Ridio1、m_Ridio4。

三、用ClassWizard生成各單選按鈕的單擊消息函數,並加入內容:

void CWEditView::OnRadio1()
{
m_Ridio1 = 0; //第一個單選按鈕被選中
}

void CWEditView::OnRadio2()
{
m_Ridio1 = 1; //第二個單選按鈕被選中
}

void CWEditView::OnRadio3()
{
m_Ridio1 = 2; //第三個單選按鈕被選中
}

void CWEditView::OnRadio4()
{
m_Ridio4 = 0; //第四個單選按鈕被選中
}

void CWEditView::OnRadio5()
{
m_Ridio4 = 1; //第五個單選按鈕被選中
}

四、設置默認按鈕:
在定義控件變量時,ClassWizard在構造函數中會把變量初值設爲-1,只需把它改爲其它值即可。
如:
//{{AFX_DATA_INIT(CWEditView)
m_Ridio1 = 0; //初始時第一個單選按鈕被選中
m_Ridio4 = 0; //初始時第四個單選按鈕被選中
//}}AFX_DATA_INIT


VC學習筆記6:旋轉控件(Spin)的使用

當單擊旋轉控件上的按鈕時,相應的編輯控件值會增大或減小。其設置的一般步驟爲:
一、在對話框中放入一個Spin控件和一個編輯控件作爲Spin控件的夥伴窗口,
設置Spin控件屬性:Auto buddy、Set buddy integer、Arrow keys
設置文本控件屬性:Number

二、用ClassWizard爲Spin控件定義變量m_Spin,爲編輯控件定義變量m_Edit,定義時注意要把m_Edit設置爲int型。

三、在對話框的OnInitDialog()函數中加入語句:
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();

m_Spin.SetBuddy( GetDlgItem( IDC_EDIT1 ) ); //設置編輯控件爲Spin控件的夥伴窗口
m_Spin.SetRange( 0, 10 ); //設置數據範圍爲0-10
return TRUE;
}

四、用ClassWizard爲編輯控件添加EN_CHANGE消息處理函數,再加入語句:
void CMyDlg::OnChangeEdit1()
{
m_Edit = m_Spin.GetPos(); //獲取Spin控件當前值
}

OK!


VC學習筆記7:程序結束時保存文件問題

在文檔-視圖結構中,用串行化自動保存文件在各種VC書上都有介紹。現在的問題是我不使用串行化,而是自己動手保存,當點擊窗口的關閉按鈕時,如何提示並保存文檔。

用ClassWizard在文檔類(CxxDoc)中添加函數CanCloseFrame(),再在其中加入保存文件的語句就可以了。
注:要保存的數據應放在文檔類(CxxDoc)或應用程序類(CxxApp)中,不要放在視圖類中。

例:
//退出程序
BOOL CEditDoc::CanCloseFrame(CFrameWnd* pFrame)
{
CFile file;
if(b_Flag) //b_Flag爲文檔修改標誌,在修改文檔時將其置爲True
{
int t;
t=::MessageBox(NULL,"文字已經改變,要存盤嗎?","警告",
MB_YESNOCANCEL | MB_ICONWARNING); //彈出提示對話框
if(t==0 || t==IDCANCEL)
return false;
if(t==IDYES)
{
CString sFilter="Text File(*.txt)|*.txt||";
CFileDialog m_Dlg(FALSE,"txt",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,(LPCTSTR)sFilter,NULL); //定製文件對話框

int k=m_Dlg.DoModal(); //彈出文件對話框
if(k==IDCANCEL || k==0)
return false;
m_PathName=m_Dlg.GetPathName(); //獲取選擇的文件路徑名

file.Open(m_PathName,CFile::modeCreate | CFile::modeWrite);
file.Write(m_Text,m_TextLen); //數據寫入文件
file.Close();
}
}
return CDocument::CanCloseFrame(pFrame);
}


VC學習筆記8:UpdateData()

對於可以接收數據的控件,如編輯控件來說,UpdateData()函數至關重要。當控件內容發生變化時,對應的控件變量的值並沒有跟着變化,同樣,當控件變量值變化時,控件內容也不會跟着變。
UpdateData()函數就是解決這個問題的。

UpdateData(true);把控件內容裝入控件變量
UpdateData(false);用控件變量的值更新控件

如:有編輯控件IDC_EDIT1,對應的變量爲字符串m_Edit1,
1、修改變量值並顯示在控件中:
m_Edit1 = _T("結果爲50");
UpdateData(false);
2、讀取控件的值到變量中:
用ClassWizard爲IDC_EDIT1添加EN_CHANGE消息處理函數,
void CEditView::OnChangeEdit1()
{
UpdateData(true);
}


  今天回到學校第一個要講的內容當然就是放假期間佈置的作業啦,嘻嘻,不要告訴別人我的程序是昨晚做的喔,而且還是有BUG在的呢!現給出我原來沒有改時候的原程序吧:
#include
#define SIZE 5

typedef struct student
{
  int num;
  char name[10];
  int score;
  float averge;
  struct student *next;
}student;

void main()
{
  FILE *fp;
  student *h,*p;
  int i;
  if( (fp=fopen("stud.txt","wb"))==NULL )
  {
    printf("Can't open the file");
    exit(1);
  }

  h=p=(student *)malloc(sizeof(student));
  for(i=0;i  {
    printf("please input num name score/n");
    scanf("%d%s%d",&p->num,p->name,&p->score); /*這裏輸入經常有莫名奇怪的問題*/
    p->averge=p->score/3;
    p->next=(student *)malloc(sizeof(student));
    p=p->next;
  }
  p->next=NULL;

  for(p=h,i=0;inext)
  {
    printf("%s",p->name);
    fwrite(p,sizeof(student),1,fp); /*這裏初以爲用指針不行*/
  }
  fclose(fp);
}

  這裏指出來兩個問題,第一個問題之前我也有遇到過,不過當時沒有理會,今天吃吃苦。不過現在網絡方便,而且CSDN高手如雲,有問題當然就是到CSDN啦(不是在賣廣告吧?哈哈)。CSDN上得知原來scanf()這個函數有個緩衝的問題,所以導致輸入次數無端端的減少,這裏有個方法就是給scanf("%d%s%d",&p->num,p->name,&p->score); 這句之上加上一個處理緩衝的函數fflush(stdin);至於用法大家查查書就行了。第二個問題得知原因之後更不是問題了,其實本身這就是對的。爲什麼我爲產生這個誤解,原因都是我試着讀入數據來看的時候產生的,下面加下一些補充後程序如下:
#include

#define SIZE 5

typedef struct student
{
  int num;
  char name[10];
  int score;
  float averge;
  struct student *next;
}student;

void main()
{
  FILE *fp;
  student *h,*p;
  student test[SIZE]; /* 加上這個定義是爲了下面測試用 */
  int i;
  if( (fp=fopen("stud.txt","wb"))==NULL )
  {
    printf("Can't open the file");
    exit(1);
  }

  h=p=(student *)malloc(sizeof(student));
  for(i=0;i  {
    printf("please input num name score/n");
    fflush(stdin); /* 這裏加上這句解決輸入緩衝問題*/
    scanf("%d%s%d",&p->num,p->name,&p->score);
    p->averge=p->score/3;
    p->next=(student *)malloc(sizeof(student));
    p=p->next;
  }
  p->next=NULL;

  for(p=h,i=0;inext)
  {
    printf("%s",p->name);
    fwrite(p,sizeof(student),1,fp); /*這裏初以爲用指針不行*/
  }
  
  /***這裏加上讀入文件***/
  for(i=0;i  {
    fread(test[ i ],sizeof(student),1,fp);
    printf("%d%s%d%3.1f/n",test[i].num, test[i].name, test[i].score, test[i].averge);
  }
  fclose(fp);
}
  看上面加上了讀入文件數據到結構數組test裏,那麼我們就看看結果吧,編譯成果,好了,你是不是根本看不到你想要的結果呢,而得到是一堆莫名奇妙的符號呢,是的,沒錯,就是因爲這點我才起初誤認爲寫入數據fwrtie對指針的問題。好了下面我們解決這個迷吧(可能有些高手已經知道了),其實就是文件指針的問題,當我們上面那個寫入到文件事那個指針已經到底了,到輸入到數組裏時當然就是不知明的數據了。
  fseek(fp,0,0);
  /***這裏加上讀入文件***/
  for(i=0;i  {
    fread(test[ i ],sizeof(student),1,fp);
    printf("%d%s%d%3.1f/n",test[i].num, test[i].name, test[i].score, test[i].averge);
  }
  在這句之前加上fseek(fp,0,0); 這個函數,這是和文件函數相配對的隨機讀入函數。這裏參數都是0是說明文件指針指向最頂,好了,看看結果是不是我們想要的結果了。
下面繼續深入研究一下文件這章吧,你有沒有想過把本身你寫的這個程序C程序顯示在屏幕上呢,當然不是用DOS的命令type 等一些其它的命令啦,就是直接用C語言程序把自身讀出來。其實這個問題實現起來太簡單了,你有看過老潭的那章嗎?記得文件COPY的那個小實例嗎?哈哈~!~!看下程序:
#include
main()
{
  FILE *fp;
  char c;
  if( (fp=fopen("當前寫的文件名","r"))==NULL )
  {
    printf("Can't open the file");
    exit(1);
  }
  c=fgetc(fp);
  whle(!feof(fp))
  {
    c=fgetch(fp);
    putchar(c);
  }
}
  記起來了嗎?沒錯就是這麼簡單啦,跟着下面的比較有挑戰性。我們把自身逆序輸出,嘻嘻,其實也不用怕。如果掌握了fseek()和ftell()這兩個文件函數就可以了,大家自己試寫寫,我的程序如下:
#include
main()
{
  FILE *fp;
  char c;
  long se;
  if( (fp=fopen("當前寫的文件名","r"))==NULL )
  {
    printf("Can't open the file");
    exit(1);
  }
  fseek(fp,0,2); /*這裏是指向最後的一個字節*/
  se=ftell(fp); /*結合上面的那個取得總字符數*/
  for(;se>=0;se--)
  {
    fseek(fp,se,0);
    fread(&c,,1,1,fp);
    puthcar(c);
  }
}
  看看,是不是很可爽很過癮,自身源程序都倒過來了。好了,文章也該告一段落了。因爲今年下午都要上學的原因,自然學的東西也多了,那麼……嘻嘻,我的字也很應該多些吧,這樣纔對得住大家啊。不過因爲今天做了很多初程的題目,所以也不太多的寫上來了,寫一個比較有用的吧,如下:
/*這個程序的作用是將一個字符數組裏大寫的字母都改爲小寫*/
void main()
{
  int i=0;
  char s[120];
  printf("Enter a string/n");
  scanf("%s",s)
  while( _____ )
  {
    if( _____ )
    s[i]=s[i]-'A'+'a';
    i++;
  }
  printf("%s/n",s);
}
  如果對於字符串這方面比較熟悉的,相信很快已經想到這題案了吧。這裏最嚇人的一句就是s[i]=s[i]-'A'+'a'; 其實也沒有什麼好怕的,大家好好想想把你的答案發到http://zhgpa.vicp.net/bbs(沒有辦法,我的站點人氣太少咯,呵呵),好了,就這樣沒完沒了的結束今天吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章