📄 openfile_win32.c
字号:
{ 0,PLATFORM_ID, PLATFORM_OK },
{ 0,OPENFILE_ID, OPENFILE_OPTIONS },
{ 1,OPENFILE_ID, OPENFILE_ENTERURL },
{ 1,OPENFILE_ID, OPENFILE_HISTORYMENU },
{ 2,OPENFILE_ID, OPENFILE_EMPTY },
{ 1,OPENFILE_ID, OPENFILE_MORE },
{ 1,OPENFILE_ID, OPENFILE_SELECTALL },
{ 1,OPENFILE_ID, OPENFILE_SELECTDIR2 },
{ 1,OPENFILE_ID, OPENFILE_SORT },
{ 2,OPENFILE_ID, OPENFILE_LABEL_NAME },
{ 2,OPENFILE_ID, OPENFILE_LABEL_TYPE },
{ 2,OPENFILE_ID, OPENFILE_LABEL_SIZE },
{ 2,OPENFILE_ID, OPENFILE_LABEL_DATE },
{ 1,OPENFILE_ID, OPENFILE_FILTER },
{ 2,OPENFILE_ID, OPENFILE_ALL_FILES },
{ 1,OPENFILE_ID, OPENFILE_ONLYNAME },
{ 1,PLATFORM_ID, PLATFORM_CANCEL },
MENUDEF_END
};
static const menudef MenuDefSmartSingle[] =
{
{ 0,PLATFORM_ID, PLATFORM_OK },
{ 0,OPENFILE_ID, OPENFILE_OPTIONS },
{ 1,OPENFILE_ID, OPENFILE_ENTERURL },
{ 1,OPENFILE_ID, OPENFILE_HISTORYMENU },
{ 2,OPENFILE_ID, OPENFILE_EMPTY },
{ 1,OPENFILE_ID, OPENFILE_SORT },
{ 2,OPENFILE_ID, OPENFILE_LABEL_NAME },
{ 2,OPENFILE_ID, OPENFILE_LABEL_TYPE },
{ 2,OPENFILE_ID, OPENFILE_LABEL_SIZE },
{ 2,OPENFILE_ID, OPENFILE_LABEL_DATE },
{ 1,OPENFILE_ID, OPENFILE_FILTER },
{ 2,OPENFILE_ID, OPENFILE_ALL_FILES },
{ 1,OPENFILE_ID, OPENFILE_ONLYNAME },
{ 1,PLATFORM_ID, PLATFORM_CANCEL },
MENUDEF_END
};
static const menudef MenuDefSmartSingleSave[] =
{
{ 0,OPENFILE_ID, OPENFILE_SAVE },
{ 0,OPENFILE_ID, OPENFILE_OPTIONS },
{ 1,OPENFILE_ID, OPENFILE_ENTERNAME },
{ 1,OPENFILE_ID, OPENFILE_ENTERURL },
{ 1,OPENFILE_ID, OPENFILE_HISTORYMENU },
{ 2,OPENFILE_ID, OPENFILE_EMPTY },
{ 1,OPENFILE_ID, OPENFILE_SORT },
{ 2,OPENFILE_ID, OPENFILE_LABEL_NAME },
{ 2,OPENFILE_ID, OPENFILE_LABEL_TYPE },
{ 2,OPENFILE_ID, OPENFILE_LABEL_SIZE },
{ 2,OPENFILE_ID, OPENFILE_LABEL_DATE },
{ 1,OPENFILE_ID, OPENFILE_FILTER },
{ 2,OPENFILE_ID, OPENFILE_ALL_FILES },
{ 1,OPENFILE_ID, OPENFILE_ONLYNAME },
{ 1,PLATFORM_ID, PLATFORM_CANCEL },
MENUDEF_END
};
static int Command(openfile* p,int i)
{
if (i>=OPENFILE_HISTORY && i<OPENFILE_HISTORY+p->HistoryCount && !p->InUpdate)
{
SetURLText(p,p->History[i-OPENFILE_HISTORY]);
PostMessage(p->Win.Wnd,WM_COMMAND,OPENFILE_GO,0);
}
else
switch (i)
{
case OPENFILE_SAVE:
Save(p);
break;
case PLATFORM_OK:
if (p->Win.Focus && p->Win.Focus->Pin.No == OPENFILE_URL)
SendMessage(p->Win.Wnd,WM_COMMAND,OPENFILE_GO,0);
else
if (p->Flags & OPENFLAG_SAVE)
Save(p);
else
Add(p);
return ERR_NONE;
case OPENFILE_TYPES-1:
*p->CurrentFileType = 0;
UpdateFileType(p,1);
break;
case OPENFILE_ALL_FILES:
*p->CurrentFileType = -1;
UpdateFileType(p,1);
break;
case OPENFILE_ONLYNAME:
p->OnlyName = !p->OnlyName;
UpdateOnlyName(p);
break;
case OPENFILE_LABEL_NAME:
case OPENFILE_LABEL_TYPE:
case OPENFILE_LABEL_SIZE:
case OPENFILE_LABEL_DATE:
if (i == OPENFILE_LABEL_DATE)
i = 3;
else
i -= OPENFILE_LABEL_NAME;
if (p->SortCol != i)
p->SortDir = 0;
else
p->SortDir = !p->SortDir;
p->SortCol = i;
UpdateSort(p);
break;
case OPENFILE_GO:
if (!p->InUpdate)
{
tcscpy_s(p->Last,TSIZEOF(p->Last),p->Path);
GetWindowText(p->WndURL,p->Path,TSIZEOF(p->Path));
if (tcsicmp(p->Last,p->Path)==0)
SavePos(p);
else
p->Last[0] = 0;
UpdateList(p,0,1);
}
break;
case OPENFILE_ENTERNAME:
WinPropFocus(&p->Win,&p->Win.Node,OPENFILE_SAVE_NAME,1);
break;
case OPENFILE_ENTERURL:
SendMessage(p->WndURL,EM_SETSYMBOLS,0,(LPARAM)SYMBOLS);
WinPropFocus(&p->Win,&p->Win.Node,OPENFILE_URL,1);
break;
case OPENFILE_SELECTDIR:
case OPENFILE_SELECTDIR2:
p->SelectDir = !p->SelectDir;
UpdateSelectDir(p);
break;
case OPENFILE_SELECTALL:
p->Multiple = 1;
UpdateMultiple(p);
SelectAll(p);
break;
case OPENFILE_MORE:
p->Multiple = !p->Multiple;
UpdateMultiple(p);
break;
}
if (i >= OPENFILE_TYPES && i < OPENFILE_TYPES+ARRAYCOUNT(p->Types,int))
{
*p->CurrentFileType = ARRAYBEGIN(p->Types,int)[i-OPENFILE_TYPES];
UpdateFileType(p,1);
}
return ERR_INVALID_PARAM;
}
static bool_t Proc(openfile* p,int Msg, uint32_t wParam, uint32_t lParam, int* Result)
{
LPNMLISTVIEW Notify;
int Style;
int FontSize;
wincontrol* Control;
bool_t HasHost;
tchar_t Mime[MAXMIME];
switch (Msg)
{
case WM_KEYDOWN:
if (wParam == VK_RETURN)
{
SendMessage(p->Win.Wnd,WM_COMMAND,OPENFILE_GO,0);
return 1;
}
if (wParam == VK_ESCAPE)
PostMessage(p->Win.Wnd,WM_CLOSE,0,0);
break;
case WM_INITMENUPOPUP:
InitMenu(p);
break;
case MSG_PREPARE:
p->CurrentFileType = (p->Flags & OPENFLAG_SINGLE) ? &p->FileTypeSingle : &p->FileType;
p->Last[0] = 0;
if (p->Win.Smartphone)
if (p->Flags & OPENFLAG_SAVE)
p->Win.MenuDef = MenuDefSmartSingleSave;
else
p->Win.MenuDef = (p->Flags & OPENFLAG_SINGLE) ? MenuDefSmartSingle : MenuDefSmart;
else
p->Win.MenuDef = (p->Flags & OPENFLAG_SINGLE) ? MenuDefSingle : MenuDef;
break;
case WM_CREATE:
if (p->Win.Smartphone)
{
p->WndGo = NULL;
p->WndURL = CreateWindow(T("EDIT"), NULL, WS_TABSTOP|WS_VISIBLE|WS_CHILD|WS_BORDER|ES_AUTOHSCROLL,
0,0,10,10,p->Win.WndDialog, NULL, p->Win.Module, NULL);
SetWindowLong(p->WndURL,GWL_USERDATA,1); // send back key to control
SendMessage(p->WndURL,EM_SETSYMBOLS,0,(LPARAM)SYMBOLS);
}
else
{
p->WndURL = CreateWindow(T("COMBOBOX"), NULL, WS_TABSTOP|WS_VISIBLE|WS_CHILD|CBS_DROPDOWN|CBS_AUTOHSCROLL,
0,0,10,10,p->Win.WndDialog, NULL, p->Win.Module, 0L);
p->WndGo = CreateWindow(T("BUTTON"),NULL,WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_NOTIFY,
0,0,10,10,p->Win.WndDialog, NULL, p->Win.Module, NULL );
SetWindowText(p->WndGo,LangStr(OPENFILE_ID,OPENFILE_GO));
FontSize = 11;
SendMessage(p->WndGo,WM_SETFONT,(WPARAM)WinFont(&p->Win,&FontSize,0),0);
}
FontSize = 12;
SendMessage(p->WndURL,WM_SETFONT,(WPARAM)WinFont(&p->Win,&FontSize,0),0);
Style = WS_TABSTOP|WS_VISIBLE|WS_CHILD|WS_VSCROLL|WS_HSCROLL|LVS_REPORT|LVS_SHOWSELALWAYS;
if (p->Win.Smartphone)
Style |= LVS_NOCOLUMNHEADER;
p->WndList = CreateWindow(T("SysListView32"), NULL, Style,
0,0,20,20, p->Win.Wnd, NULL, p->Win.Module, NULL);
ListView_SetExtendedListViewStyle(p->WndList,LVS_EX_FULLROWSELECT);
if (WinUnitToPixelX(&p->Win,72) >= 96*2)
ListView_SetImageList(p->WndList,
ImageList_LoadBitmap(p->Win.Module,MAKEINTRESOURCE(IDB_FICON32),32,0,0xFF00FF), LVSIL_SMALL);
else
ListView_SetImageList(p->WndList,
ImageList_LoadBitmap(p->Win.Module,MAKEINTRESOURCE(IDB_FICON16),16,0,0xFF00FF), LVSIL_SMALL);
AddCol(p,0,LangStr(OPENFILE_ID,OPENFILE_LABEL_NAME),max(15,p->DlgWidth[0]),LVCFMT_LEFT);
AddCol(p,1,LangStr(OPENFILE_ID,OPENFILE_LABEL_TYPE),max(15,p->DlgWidth[1]),LVCFMT_LEFT);
AddCol(p,2,LangStr(OPENFILE_ID,OPENFILE_LABEL_SIZE),max(15,p->DlgWidth[2]),LVCFMT_RIGHT);
AddCol(p,3,LangStr(OPENFILE_ID,OPENFILE_LABEL_DATE),max(15,p->DlgWidth[3]),LVCFMT_LEFT);
p->OnlyNameState = 0;
p->LastClick = -1;
p->Top = 0;
p->Win.LabelWidth = 40;
if (p->Flags & OPENFLAG_SAVE)
{
if (!p->FileTypeSave)
p->FileTypeSave = NodeEnumClass(NULL,p->Class);
p->Top += 2;
WinPropValue(&p->Win,&p->Top,&p->Win.Node,OPENFILE_SAVE_NAME);
p->Top += 2;
WinPropValue(&p->Win,&p->Top,&p->Win.Node,OPENFILE_SAVE_TYPE);
p->Top = WinUnitToPixelY(&p->Win,p->Top+2);
}
Control = WinPropNative(&p->Win,&p->Win.Node,OPENFILE_LIST);
Control->Control = p->WndList;
Control->ListView = 1;
Control->External = 1;
Control = WinPropNative(&p->Win,&p->Win.Node,OPENFILE_URL);
Control->Control = p->WndURL;
Control->External = 1;
p->SelectDir = 0;
Resize(p);
GetMime(p->Path,Mime,TSIZEOF(Mime),&HasHost);
UpdateMenu(p);
UpdateFileType(p,HasHost?0:2);
UpdateSort(p);
UpdateMultiple(p);
UpdateSelectDir(p);
UpdateOnlyName(p);
if (p->Flags & OPENFLAG_SAVE)
WinPropFocus(&p->Win,&p->Win.Node,OPENFILE_SAVE_NAME,1);
else
if (HasHost)
WinPropFocus(&p->Win,&p->Win.Node,OPENFILE_URL,1);
break;
case WM_DESTROY:
if (!p->OnlyNameState)
{
p->DlgWidth[0] = GetColWidth(p,0);
p->DlgWidth[1] = GetColWidth(p,1);
p->DlgWidth[2] = GetColWidth(p,2);
p->DlgWidth[3] = GetColWidth(p,3);
}
ClearList(p);
break;
case WM_SIZE:
Resize(p);
break;
case WM_NOTIFY:
Notify = (LPNMLISTVIEW) lParam;
if (Notify->hdr.hwndFrom == p->WndList)
{
if (Notify->hdr.code == NM_SETFOCUS)
WinPropFocus(&p->Win,&p->Win.Node,OPENFILE_LIST,0);
// mouse double click in multiple mode
if (p->Multiple && !(p->Flags & OPENFLAG_SINGLE) &&
Notify->hdr.code==LVN_ITEMACTIVATE && Notify->iItem==p->LastClick &&
Notify->ptAction.x >= 0 && Notify->ptAction.y >= 0)
{
LVITEM Item;
Item.iItem=Notify->iItem;
Item.iSubItem=0;
Item.mask=LVIF_PARAM;
if (ListView_GetItem(p->WndList,&Item) && Item.lParam && (((openitem*)Item.lParam)->Image != IMG_DIR || p->SelectDir))
{
SelectIfNone(p,Notify->iItem);
PostMessage(p->Win.Wnd,WM_COMMAND,PLATFORM_OK,0);
return 0;
}
}
if (Notify->hdr.code==LVN_ITEMACTIVATE || Notify->hdr.code==NM_CLICK)
{
LVITEM Item;
Item.iItem=Notify->iItem;
Item.iSubItem=0;
Item.mask=LVIF_PARAM;
p->LastClick = Notify->iItem;
if (ListView_GetItem(p->WndList,&Item))
{
tchar_t Path[MAXPATH];
if (!Item.lParam) // ".."
{
if (UpperPath(p->Path,p->Last,TSIZEOF(p->Last)))
{
p->LastClick = -1;
UpdateList(p,1,1);
}
}
else
if (((openitem*)Item.lParam)->Image==IMG_DIR && !p->SelectDir) // directory
{
AbsPath(Path,TSIZEOF(Path),((openitem*)Item.lParam)->FileName,p->Base);
tcscpy_s(p->Path,TSIZEOF(p->Path),Path);
p->Last[0] = 0;
p->LastClick = -1;
UpdateList(p,1,1);
}
else
{
if (p->Multiple && !(p->Flags & OPENFLAG_SINGLE))
{
int State = ListView_GetItemState(p->WndList,Notify->iItem,LVIS_SELECTED) & LVIS_SELECTED;
p->OwnSelect = 1;
ListView_SetItemState(p->WndList,Notify->iItem,(State ^ LVIS_SELECTED)|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED);
p->OwnSelect = 0;
if (p->KeyClick)
keybd_event(VK_DOWN,1,0,0);
}
else
{
if (p->Flags & OPENFLAG_SAVE)
SetSaveName(p,Notify->iItem);
else
{
SelectIfNone(p,Notify->iItem);
PostMessage(p->Win.Wnd,WM_COMMAND,PLATFORM_OK,0);
}
}
}
}
p->KeyClick = 0;
}
if (Notify->hdr.code==LVN_KEYDOWN && ((LPNMLVKEYDOWN)lParam)->wVKey == VK_ESCAPE)
PostMessage(p->Win.Wnd,WM_CLOSE,0,0);
if (p->Multiple && !(p->Flags & OPENFLAG_SINGLE))
{
// manual focus and selection
if (Notify->hdr.code==LVN_KEYDOWN)
{
// pass one focus change after keyboard
LPNMLVKEYDOWN Key = (LPNMLVKEYDOWN) lParam;
if (Key->wVKey == VK_RETURN)
p->KeyClick = 1;
if (Key->wVKey == VK_UP ||
Key->wVKey == VK_PRIOR ||
Key->wVKey == VK_HOME)
{
if (ListView_GetItemState(p->WndList,0,LVIS_FOCUSED)!=LVIS_FOCUSED)
p->NextFocus = 1;
}
if (Key->wVKey == VK_DOWN ||
Key->wVKey == VK_NEXT ||
Key->wVKey == VK_END)
{
if (ListView_GetItemState(p->WndList,ListView_GetItemCount(p->WndList)-1,LVIS_FOCUSED)!=LVIS_FOCUSED)
p->NextFocus = 1;
}
}
if (p->NextFocus && Notify->hdr.code==LVN_ITEMCHANGED && (Notify->uChanged & LVIF_STATE) &&
((Notify->uOldState ^ Notify->uNewState) & LVIS_FOCUSED))
{
// clear NextFocus if the new focus has been set
if (Notify->uNewState & LVIS_FOCUSED)
p->NextFocus = 0;
if ((Notify->uOldState ^ Notify->uNewState) & LVIS_SELECTED)
{
// restore old selection
p->OwnSelect = 1;
ListView_SetItemState(p->WndList,Notify->iItem,Notify->uOldState & LVIS_SELECTED,LVIS_SELECTED);
p->OwnSelect = 0;
}
}
if (!p->OwnSelect && Notify->hdr.code==LVN_ITEMCHANGING && (Notify->uChanged & LVIF_STATE))
{
// let focus change pass (if NextFocus is set)
if (!p->NextFocus || !((Notify->uOldState ^ Notify->uNewState) & LVIS_FOCUSED))
{
*Result = 1;
return 1;
}
}
}
if (Notify->hdr.code==LVN_COLUMNCLICK)
{
if (p->SortCol != Notify->iSubItem)
p->SortDir = 0;
else
p->SortDir = !p->SortDir;
p->SortCol = Notify->iSubItem;
UpdateSort(p);
}
}
break;
}
return 0;
}
static void Delete(openfile* p)
{
int i;
#ifndef REGISTRY_GLOBAL
NodeRegSave(&p->Win.Node);
#endif
ArrayClear(&p->Types);
for (i=0;i<MAXHISTORY;++i)
free(p->History[i]);
}
static int Create(openfile* p)
{
p->OnlyName = p->Win.Smartphone;
p->DlgWidth[1] = 40;
p->DlgWidth[2] = 46;
p->DlgWidth[3] = 60;
p->Class = MEDIA_CLASS;
p->CurrentFileType = &p->FileType;
#ifdef TARGET_WIN32
p->DlgWidth[0] = 150;
p->Win.WinWidth = 320;
#else
p->DlgWidth[0] = 90;
p->Win.WinWidth = 180;
#endif
p->Win.WinHeight = 240;
p->Win.Flags |= WIN_DIALOG;
p->Win.OwnDialogSize = 1;
p->Win.Command = (wincommand)Command;
p->Win.Proc = Proc;
p->Win.DialogProc = DialogProc;
p->Win.Node.Enum = Enum;
p->Win.Node.Get = Get;
p->Win.Node.Set = Set;
return ERR_NONE;
}
static const nodedef OFile =
{
sizeof(openfile)|CF_GLOBAL,
OPENFILE_ID,
WIN_CLASS,
PRI_DEFAULT,
(nodecreate)Create,
(nodedelete)Delete,
};
void OpenFile_Init()
{
NodeRegisterClass(&OFile);
}
void OpenFile_Done()
{
NodeUnRegisterClass(OPENFILE_ID);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -