2008 November 17th Monday (十一月 十七日 月曜日)

本文介绍了Erlang编程语言的特点,包括轻量级进程间的通信机制及宏定义等高级特性。此外,还详细讲解了如何在Windows中利用自定义资源存储二进制数据,并介绍了菜单资源的加载与修改方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   Erlang is an interesting programming language.  Every light process in erlang is separated, they must communicate with messages.  So, send and receive messages
is primitive operator in erlang, they are more easy to run than in other language, such as, Java, C++, Python, and so forth.  There are other features in erlang.  But,
many a feature come from prolog, scheme, such as tail rescursion, list, tuple, unification, etc.  To learn erlang is easy, but master it is not easy.

  You can find out the preprocess macro is alike that of C programming language.

-module(macros_demo).
-export([test/0]).

-ifdef(debug).
-define(LOG(X), io:format("{~p,~p}: ~p~n", [?MODULE, ?LINE, X])).
-else.
-define(LOG(X), true).
-endif.
-define(Square(X),X*X).

-compile(export_all).

test() ->
    A=3,
    ?LOG(A),
    B=?Square(A),
    io:format("square(~w) is ~w~n",[A,B]).

  To run it.

17> c(macros_demo).
{ok,macros_demo}
18> macros_demo:test().
square(3) is 9

  After Compiled with debug.

19> c(macros_demo,{d,debug}).
{ok,macros_demo}
20> macros_demo:test().
{macros_demo,11}: 3
square(3) is 9
ok

  There is a prolog program.

%% exercise

assign(X, Y) -->
    left(X), [:=], right(Y), [;].

left(X, Start, End) :-
    [ X | End ] = Start,
    atomic(X).

right(Y, Start, End) :-
    [ Y | End ] = Start,
    number(Y).

Custom Resources

  Windows also defines a "custom resource," also called the "user-defined resource" (where the user is you, the programmer,
rather than the lucky person who gets to use your program). The custom resource is convenient for attaching miscellaneous
data to your .EXE file and obtaining access to that data within the program. The data can be in absolutely any format you want.
The Windows functions that a program uses to access the custom resource cause Windows to load the data into memory and return
a pointer to it. You can do whatever you want with that data. You'll probably find this to be a more convenient way to store
and access miscellaneous private data than storing it in external files and accessing it with file input functions.

  For instance, suppose you have a file called BINDATA.BIN that contains a bunch of data that your program needs for display
purposes. This file can be in any format you choose. If you have a MYPROG.RC resource script in your MYPROG project, you can
create a custom resource in Developer Studio by selecting Resource from the Insert menu and pressing the Custom button. Type in
a type name by which the resource is to be known: for example, BINTYPE. Developer Studio will then make up a resource name
(in this case, IDR_BINTYPE1) and display a window that lets you enter binary data. But you don't need to do that. Click the
IDR_BINTYPE1 name with the right mouse button, and select Properties. Then you can enter a filename: for example, BINDATA.BIN.

  The resource script will then contain a statement like this:

IDR_BINTYPE1 BINTYPE BINDATA.BIN

  This statement looks just like the ICON statement in ICONDEMO, except that the resource type BINTYPE is something we've just
made up. As with icons, you can use text names rather than numeric identifiers for the resource name.

  When you compile and link the program, the entire BINDATA.BIN file will be bound into the MYPROG.EXE file.

  During program initialization (for example, while processing the WM_CREATE message), you can obtain a handle to this resource:

hResource = LoadResource (hInstance,
            FindResource (hInstance, TEXT ("BINTYPE"),
                          MAKEINTRESOURCE (IDR_BINTYPE1))) ;

  The variable hResource is defined with type HGLOBAL, which is a handle to a memory block. Despite its name, LoadResource does
not actually load the resource into memory. The LoadResource and FindResource functions used together like this are essentially
equivalent to the LoadIcon and LoadCursor functions. In fact, LoadIcon and LoadCursor use the LoadResource and FindResource functions.

When you need access to the text, call LockResource:

pData = LockResource (hResource) ;

  LockResource loads the resource into memory (if it has not already been loaded) and returns a pointer to it. When you're finished
with the resource, you can free it from memory:

FreeResource (hResource) ;

  The resource will also be freed when your program terminates, even if you don't call FreeResource.

Referencing the Menu in Your Program

  Most Windows applications have only one menu in the resource script. You can give the menu a text name that is the same as the name
of the program. Programmers often use the name of the program as the name of the menu so that the same character string can be used for
the window class, the name of the program's icon, and the name of the menu. The program then makes reference to this menu in the definition
of the window class:

wndclass.lpszMenuName = szAppName ;

  Although specifying the menu in the window class is the most common way to reference a menu resource, that's not the only way to do it.
A Windows application can load a menu resource into memory with the LoadMenu function, which is similar to the LoadIcon and LoadCursor
functions described earlier. LoadMenu returns a handle to the menu. If you use a name for the menu in the resource script, the statement
looks like this:

hMenu = LoadMenu (hInstance, TEXT ("MyMenu")) ;

  If you use a number, the LoadMenu call takes this form:

hMenu = LoadMenu (hInstance, MAKEINTRESOURCE (ID_MENU)) ;

  You can then specify this menu handle as the ninth parameter to CreateWindow:

hwnd = CreateWindow (TEXT ("MyClass"), TEXT ("Window Caption"),
                     WS_OVERLAPPEDWINDOW,
                     CW_USEDEFAULT, CW_USEDEFAULT,
                     CW_USEDEFAULT, CW_USEDEFAULT,
                     NULL, hMenu, hInstance, NULL) ;

  In this case, the menu specified in the CreateWindow call overrides any menu specified in the window class. You can think of the menu
in the window class as being a default menu for the windows based on the window class if the ninth parameter to CreateWindow is NULL.
Therefore, you can use different menus for several windows based on the same window class. You can also have a NULL menu name in the
window class and a NULL menu handle in the CreateWindow call and assign a menu to a window after the window has been created:

SetMenu (hwnd, hMenu) ;

Changing the Menu

  We've already seen how the AppendMenu function can be used to define a menu entirely within a program and to add menu items to the
system menu. Prior to Windows 3.0, you would have been forced to use the ChangeMenu function for this job. ChangeMenu was so versatile that
it was one of the most complex functions in all of Windows (at least at that time). Times have changed. Many other current functions are
now more complex than ChangeMenu ever was, and ChangeMenu has been replaced with five newer functions:

  * AppendMenu Adds a new item to the end of a menu.

  * DeleteMenu Deletes an existing item from a menu and destroys the item.

  * InsertMenu Inserts a new item into a menu.

  * ModifyMenu Changes an existing menu item.

  * RemoveMenu Removes an existing item from a menu.
 
  The difference between DeleteMenu and RemoveMenu is important if the item is a popup menu. DeleteMenu destroys the popup menu-but
RemoveMenu does not.

在Java中,如果你想要设置一个定时任务,使其在每年的11月30日触发,你可以使用`java.util.Calendar`类配合`ScheduledExecutorService`或`TimerTask`。但是,Java本身并没有直接提供精确到每天的定时器,所以通常我们会选择每小时检查当前日期,然后在必要时执行任务。 以下是一个示例代码片段,展示了如何通过`java.time`包(Java 8及以上版本)来定期检查日期: ```java import java.time.LocalDate; import java.time.ZoneId; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledFuture; public class YearlyNovemberThirty { private static ScheduledFuture<?> task; public static void main(String[] args) { checkNovemberThirty(); // 使用固定延迟和循环检查 Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> checkNovemberThirty(), 0, 1, TimeUnit.HOURS); } private static void checkNovemberThirty() { LocalDate today = LocalDate.now(ZoneId.systemDefault()); if (today.getMonthValue() == 11 && today.getDayOfMonth() == 30) { executeYourTask(); // 替换为你实际的任务代码 cancelTaskIfNotRequired(); // 可能需要取消任务以防持续运行 } } private static synchronized void cancelTaskIfNotRequired() { if (task != null && !task.isCancelled()) { task.cancel(false); // 假设任务不是必需的,否则应处理更复杂的逻辑 } } private static void executeYourTask() { // 这里编写你的具体任务代码 System.out.println("Task executed on November 30th"); } } ``` 在这个例子中,我们每小时检查一次当前日期,如果发现是11月30日,就执行相应的任务并考虑是否取消后续的任务检查。请注意,这并不是绝对精确的每年11月30日,因为系统可能会有时间调整导致实际触发时间稍有偏差。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值